Феерия с inline в C99 и GCC 5.1
От: Tilir Россия http://tilir.livejournal.com
Дата: 03.07.15 12:37
Оценка: 18 (3)
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
Отредактировано 06.07.2015 10:34 Tilir . Предыдущая версия . Еще …
Отредактировано 03.07.2015 12:39 Tilir . Предыдущая версия .
Отредактировано 03.07.2015 12:38 Tilir . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.