当我尝试在 Linux 上使用 gcc -std=c99
编译它时,编译器提示不知道 struct timespec
。但是,如果我在没有 -std=c99
的情况下编译它,一切正常。
#include <time.h>
int main(void)
{
struct timespec asdf;
return 0;
}
为什么会这样,有没有办法让它与 -std=c99
一起工作?
最佳答案
显式启用 POSIX 功能
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) 中的定义。
- 如果你想要 POSIX 2008 (SUS v4) Material ,用途
_XOPEN_SOURCE 700
- 如果你想要 POSIX 2004 (SUS v3) Material ,用途
_XOPEN_SOURCE 600
- 如果你想要 POSIX 1995 (SUS v2, 1997) Material ,使用
_XOPEN_SOURCE 500
如评论中所述,使用 _XOPEN_SOURCE
在严格的 POSIX 上严格启用 XSI(X/开放系统接口(interface))扩展,但是您很少需要 POSIX 而不是 XSI。您通常应该指定 _XOPEN_SOURCE
而不是与_POSIX_C_SOURCE
混在一起.参见 The Compilation Environment 上的(POSIX 2018)有关功能宏的更多信息。
对于我 2010 年的系统,POSIX 2008 不像 POSIX 2004 那样广泛可用,所以这就是我使用的 - 但 YMMV。请注意,SUS v3 和 v4 都需要 C99 编译。至少在 Solaris 上,使用 C89 失败了。
GCC 提供 -std=gnuXX
选项
如果指定 -std=c11
到 GCC(或模拟 GCC 的 Clang),则仅启用标准 C 定义。如果你使用 -std=gnu11
, 那么 POSIX 和标准 C 的其他扩展在默认情况下是可见的。
请注意 GCC 4.x 和更早版本使用 -std=gnu90
(对应C90 plus extensions)默认。 GCC 5.x 及更高版本使用 -std=gnu11
默认情况下。从来没有启用 -std=gnu99
的 GCC 版本默认情况下。
使用header控制POSIX版本信息
我现在(2019 年)使用 header 来封装此信息,以便将来的更改只需要更改单个 header ,而不是每个使用 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 */
您可以使用此 header 中的信息,而无需 Stack Overflow 使用的“CC by-sa 3.0”许可通常要求的归属和版权声明。此代码在我的 SOQ 中可用(堆栈溢出问题)GitHub 上的存储库作为文件 posixver.h
在src/libsoq子目录。
C11 定义 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
自动定义。
关于c - 带有 -std=c99 的 GCC 提示不知道 struct timespec,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3875197/