Во время игры с настройками оптимизации я заметил интересное явление: функции, принимающие переменное количество аргументов (...
), никогда не казались вложенными. (Очевидно, что это поведение специфично для компилятора, но я тестировал несколько разных систем.)
Например, компилирование следующей небольшой программы:
#include <stdarg.h>
#include <stdio.h>
static inline void test(const char *format, ...)
{
va_list ap;
va_start(ap, format);
vprintf(format, ap);
va_end(ap);
}
int main()
{
test("Hello %s\n", "world");
return 0;
}
как представляется, всегда приводит к (возможно, искалеченному) символу test
, появляющемуся в результирующем исполняемом файле (тестируется с помощью Clang и GCC в режимах C и С++ в MacOS и Linux). Если изменить подпись test()
, чтобы взять простую строку, которая передается в printf()
, функция вставляется из -O1
вверх обоими компиляторами, как вы ожидали.
Я подозреваю, что это связано с магией вуду, используемой для реализации varargs, но как это обычно делается, это для меня загадка. Кто-нибудь может рассказать мне о том, как компиляторы обычно реализуют функции vararg и почему это, по-видимому, предотвращает inlining?