![](/img/trans.png)
[英]Why does gcc not complain about htons() but complains about getaddrinfo() when compiled with -std=c99?
[英]GCC with -std=c99 complains about not knowing struct timespec
当我尝试在 Linux 上使用gcc -std=c99
编译它时,编译器抱怨不知道struct timespec
。 但是,如果我在没有-std=c99
情况下编译它,一切正常。
#include <time.h>
int main(void)
{
struct timespec asdf;
return 0;
}
为什么会这样,有没有办法让它与-std=c99
一起工作?
timespec 来自 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;
}
顶部的节是我目前使用的 - 它根据您使用的是 C99 还是 C89 编译器触发来自单一 UNIX 规范 (SUS) 的定义。
_XOPEN_SOURCE 700
_XOPEN_SOURCE 600
_XOPEN_SOURCE 500
如评论中所述,使用_XOPEN_SOURCE
严格启用 XSI(X/开放系统接口)扩展而不是严格的 POSIX,但您想要 POSIX 而不是 XSI 的情况非常少见。 您通常应该指定_XOPEN_SOURCE
而不是_POSIX_C_SOURCE
。 有关功能宏的更多信息,请参阅编译环境上的(POSIX 2018)。
对于我 2010 年的系统,POSIX 2008 不像 POSIX 2004 那样广泛可用,所以这就是我使用的 - 但 YMMV。 请注意,SUS v3 和 v4 都需要 C99 编译。 至少在 Solaris 上,使用 C89 失败了。
-std=gnuXX
选项如果您为 GCC(或 Clang 模拟 GCC)指定-std=c11
,则仅启用标准 C 定义。 如果您使用-std=gnu11
,则默认情况下可以看到 POSIX 和标准 C 的其他扩展。
请注意,GCC 4.x 及更早版本默认使用-std=gnu90
(对应于 C90 加扩展)。 GCC 5.x 及更高版本默认使用-std=gnu11
。 默认情况下,从来没有启用-std=gnu99
的 GCC 版本。
我现在(2019 年)使用标头来封装此信息,以便将来的更改只需要更改单个标头,而不是每个使用 POSIX 功能的源文件。 随着时间的推移和 POSIX 2008 的流行,从多个源文件中编辑旧的节是一件痛苦的事情。
/*
@(#)File: $RCSfile: posixver.h,v $
@(#)Version: $Revision: 1.4 $
@(#)Last changed: $Date: 2017/06/18 00:15:42 $
@(#)Purpose: Request appropriate POSIX and X/Open Support
@(#)Author: J Leffler
@(#)Copyright: (C) JLSS 2010-2017
*/
/*TABSTOP=4*/
#ifndef JLSS_ID_POSIXVER_H
#define JLSS_ID_POSIXVER_H
/*
** Include this file before including system headers. By default, with
** C99 support from the compiler, it requests POSIX 2008 support. With
** C89 support only, it requests POSIX 1997 support. Override the
** default behaviour by setting either _XOPEN_SOURCE or _POSIX_C_SOURCE.
*/
/* _XOPEN_SOURCE 700 is loosely equivalent to _POSIX_C_SOURCE 200809L */
/* _XOPEN_SOURCE 600 is loosely equivalent to _POSIX_C_SOURCE 200112L */
/* _XOPEN_SOURCE 500 is loosely equivalent to _POSIX_C_SOURCE 199506L */
#if !defined(_XOPEN_SOURCE) && !defined(_POSIX_C_SOURCE)
#if defined(__cplusplus)
#define _XOPEN_SOURCE 700 /* SUS v4, POSIX 1003.1 2008/13 (POSIX 2008/13) */
#elif __STDC_VERSION__ >= 199901L
#define _XOPEN_SOURCE 700 /* SUS v4, POSIX 1003.1 2008/13 (POSIX 2008/13) */
#else
#define _XOPEN_SOURCE 500 /* SUS v2, POSIX 1003.1 1997 */
#endif /* __STDC_VERSION__ */
#endif /* !_XOPEN_SOURCE && !_POSIX_C_SOURCE */
#endif /* JLSS_ID_POSIXVER_H */
您可以使用此标题中的信息,而无需 Stack Overflow 使用的“CC by-sa 3.0”许可通常要求的归属和版权声明。 此代码是我提供SOQ (堆栈溢出问题)在GitHub存储库中的文件posixver.h
在SRC / libsoq子目录。
struct timespec
请注意, C11定义了struct timespec
,并且以与 POSIX(首先定义它)兼容的方式进行定义。
标题<time.h>
定义了类型。 使用它的三个函数在<threads.h>
中声明,另一个在<time.h>
:
当然,这些也是 C17 (C18) 的一部分。 您必须使用-std=c11
或类似(GCC 9.2.0 似乎识别-std=c17
和-std=c18
以及-std=c2x
用于下一版本的标准)为类型struct timespec
自动定义。
我建议使用-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。 这是包装 timespec 定义的预处理器条件。 _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. */
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.