GCC с -std=c99 жалуется на то, что не знает struct timespec

Когда я пытаюсь скомпилировать это на Linux с gcc -std=c99компилятор жалуется на незнание struct timespec, Однако, если я скомпилирую это без -std=c99 все отлично работает

#include <time.h>

int main(void)
{
  struct timespec asdf;
  return 0;
}

Почему это так и есть ли способ заставить его работать с -std=c99?

2 ответа

Временная спецификация происходит из POSIX, поэтому вы должны "включить" определения POSIX:

#if __STDC_VERSION__ >= 199901L
#define _XOPEN_SOURCE 600
#else
#define _XOPEN_SOURCE 500
#endif /* __STDC_VERSION__ */

#include <time.h>

void blah(struct timespec asdf)
{
}

int main()
{
    struct timespec asdf;
    return 0;
}

Раздел в верхней части - это то, чем я сейчас пользуюсь - он запускает определения из Single UNIX Specification (SUS), основанные на том, используете ли вы компилятор C99 или C89.

  • Если вы хотите материал POSIX 2008 (SUS v4), используйте _XOPEN_SOURCE 700
  • Если вы хотите материал POSIX 2004 (SUS v3), используйте _XOPEN_SOURCE 600
  • Если вы хотите материал POSIX 1995 (SUS v2, 1997), используйте _XOPEN_SOURCE 500

Для моих систем POSIX 2008 не так широко доступен, как 2004, так что это то, что я использую - но YMMV. Обратите внимание, что для SUS v3 и v4 требуется компиляция C99. На Solaris, по крайней мере, использование C89 не удастся.

Я бы порекомендовал компилировать с -std=gnu99,

Чтобы уточнить это. По умолчанию gcc компилируется с -std=gnu89. Вот результаты для следующего исходного кода.

#include <time.h>

int main() {
    struct timespec asdf;
    return 0;
}

[1:25pm][wlynch@cardiff /tmp] gcc -std=gnu89 foo.c
[1:26pm][wlynch@cardiff /tmp] gcc -std=gnu99 foo.c

[1:25pm][wlynch@cardiff /tmp] gcc -std=c89 foo.c
foo.c: In function ‘main’:
foo.c:4: error: storage size of ‘asdf’ isn’t known

[1:26pm][wlynch@cardiff /tmp] gcc -std=c99 foo.c
foo.c: In function ‘main’:
foo.c:4: error: storage size of ‘asdf’ isn’t known

Добавление -D_GNU_SOURCE в ваш CFLAGS также будет работать.

gcc test.c -o test -std=c99 -D_GNU_SOURCE

Взгляните на /usr/include/time.h. Это условное выражение препроцессора, которое является оболочкой для определения времени. _GNU_SOURCE включает __USE_POSIX199309.

#if (!defined __timespec_defined                    \
 && ((defined _TIME_H                       \
  && (defined __USE_POSIX199309                 \
      || defined __USE_ISOC11))                 \
 || defined __need_timespec))
 # define __timespec_defined 1                                                                                                                                                                                                                 
 struct timespec
 {
    __time_t tv_sec;        /* Seconds.  */
    __syscall_slong_t tv_nsec;  /* Nanoseconds.  */
 }; 
Другие вопросы по тегам