Hi,
Не все знают, что в GCC начиная с 5.0 стандартом по умолчанию сделали C99 (UPD: на самом деле GNU11, то есть C11 + GNU extensions)
Но это является источником радости. Надеюсь этот пост убережет кого-то из тех, кто пойдет по моим следам (перевод немаленького проекта на новый компилятор).
Итак вы берете некий код, который кажется не содержит никаких ошибок:
#include <stdlib.h>
#include <stdarg.h>
inline void debug(int n,...)
{
va_list ap;
va_start( ap, n );
va_end( ap );
}
int main(void)
{
debug(0, 1);
exit(0);
}
Компилируете его GCC 5.1 для x86 и получаете...
/tmp/ccSYThQj.o: In function `main':
repro.c: (.text+0x14): undefined reference to `debug'
ШТОА, думаете вы, как так, неужели ошибка в компиляторе. Как он выбросил функцию debug, если вот же она используется.
Но стоп.
Легко видеть, что с опцией --std=gnu90 все работает, что с опцией --std=c99 все не работает даже на старых версиях GCC где все работает по умолчанию и это значит... что семантика слова inline в C99 изменилась (6.7.4, особенно пункт 6)
Теперь вы должны писать либо вот так:
static inline void debug(const char *msg,...)
{
/* ... */
}
либо добавлять extern definition
#include <stdlib.h>
#include <stdarg.h>
void debug(const char *msg,...);
inline void debug(const char *msg,...)
{
va_list ap;
va_start( ap, msg );
va_end( ap );
}
int main(void)
{
debug(0, 1);
exit(0);
}
Иначе компилятор действительно имеет право выкинуть эту штуку молча и игнорировать все имеющиеся ссылки (см. также
bugzilla).
Вот такие дела.
P.S. Может это баян давно и я один до сих пор в танке, но поиском не нашлось.
---
With best regards, Konstantin