为什么clock_gettime不编译时使用C99?



为什么这个C代码可以在C99中编译?我应该读什么来了解更多?

我不能发布,除非我添加更多的文本所以这里有一些无意义的文本因为我认为没有什么可以说的

$ cat m.c
#include <stdio.h>
#include <time.h>
int main() {
struct timespec time;
int res = clock_gettime(CLOCK_REALTIME, &time);
printf("%d %ld %ldn", res, time.tv_sec, time.tv_nsec);
return 0;
}

$ clang m.c && ./a.out && rm ./a.out
0 1631386905 774654955

$ clang -std=c99 m.c && ./a.out && rm ./a.out
m.c:4:18: error: variable has incomplete type 'struct timespec'
struct timespec time;
^
m.c:4:9: note: forward declaration of 'struct timespec'
struct timespec time;
^
m.c:5:12: warning: implicit declaration of function 'clock_gettime' is invalid in C99 [-Wimplicit-function-declaration]
int res = clock_gettime(CLOCK_REALTIME, &time);
^
m.c:5:26: error: use of undeclared identifier 'CLOCK_REALTIME'
int res = clock_gettime(CLOCK_REALTIME, &time);
^
1 warning and 2 errors generated.

这是因为使用-std=c99选项定义了一个宏,导致clock_gettime的声明被隐藏。

GNU C库可以公开其函数的不同版本,或者完全隐藏它们,这取决于用户代码的期望。用户代码通过定义某些特定命名的宏(称为特性测试宏,尽管这有点用词不当)来声明这些期望,这些宏具有GNU C库头文件识别的预先确定的值。一个这样的宏是__STRICT_ANSI__,如果使用了-std=cXX中的任何一个选项,它是隐式定义的。

引用feature_test_macros(7):

__STRICT_ANSI__

当使用-std=c99-ansi标志调用时,该宏由gcc(1)隐式定义。

[…]

如果显式定义了__STRICT_ANSI___ISOC99_SOURCE_ISOC11_SOURCE(自glibc 2.18起)、_POSIX_SOURCE_POSIX_C_SOURCE_XOPEN_SOURCE_XOPEN_SOURCE_EXTENDED(glibc 2.11及更早版本)、_BSD_SOURCE(glibc 2.19及更早版本)、_SVID_SOURCE(glibc 2.19及更早版本)中的任何一个,则默认不定义_BSD_SOURCE_SVID_SOURCE_DEFAULT_SOURCE

使用-std=gnuXX选项代替-std=cXX不会导致__STRICT_ANSI__被定义;它还支持对C语言的GNU扩展。如果您想禁用这些语言扩展,您可以将#define _DEFAULT_SOURCE 1放在文件的最顶部,以公开C库否则会公开的所有符号(或者可能是另一个功能测试宏来调整库接口以满足您的喜好)。一个显式的特性测试宏将优先于__STRICT_ANSI__

相关内容

  • 没有找到相关文章

最新更新