c - 带有 -std=c99 的 GCC 提示不知道 struct timespec

标签 c posix c99 timespec

当我尝试在 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.hsrc/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/

相关文章:

c - 指针声明和函数调用中的奇怪 C 语法

c - 从 fds_bits 中提取文件描述符

c - 为什么要销毁 pthread_cond_t 和 pthread_mutex_t?

c - `pixel (*copy)[rows] = malloc(cols * sizeof (*copy))` 需要调用多少次 free()

c99 __restrict 和编译器优化

c++ - 为什么要为结构的多个数据成员而不是单个成员添加填充?

c - 返回指向静态(外部函数)数组的指针

c - 显示ASCII字符的十六进制值

c - CLOCK_TAI 的纪元是什么?

c - C宏中参数的变量号