带有-std=c99的GCC抱怨不知道struct timespec

带有-std=c99的GCC抱怨不知道struct timespec,c,posix,c99,timespec,C,Posix,C99,Timespec,当我试图在Linux上用gcc-std=c99编译这个时,编译器抱怨不知道struct timespec。但是,如果我编译这个文件时没有-std=c99,一切正常 #include <time.h> int main(void) { struct timespec asdf; return 0; } #包括 内部主(空) { 结构timespec asdf; 返回0; } 这是为什么?有没有办法让它继续使用-std=c99?我建议使用-std=gnu99编译 对此进行详

当我试图在Linux上用
gcc-std=c99
编译这个时,编译器抱怨不知道
struct timespec
。但是,如果我编译这个文件时没有
-std=c99
,一切正常

#include <time.h>

int main(void)
{
  struct timespec asdf;
  return 0;
}
#包括
内部主(空)
{
结构timespec asdf;
返回0;
}

这是为什么?有没有办法让它继续使用
-std=c99

我建议使用
-std=gnu99
编译

对此进行详细说明。默认情况下,gcc使用-std=gnu89编译。下面是以下源代码的结果

#include <time.h>

int main() {
    struct timespec asdf;
    return 0;
}
显式启用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;
}
您可以使用此标题中的信息,而无需Stack Overflow使用的“CC by sa 3.0”许可证通常要求的归属和版权声明。此代码在GitHub上的my(Stack Overflow Questions)存储库中的子目录下的文件
posixver.h
中提供

C11定义了
struct timespec
请注意,它定义了
struct timespec
,并且以与POSIX兼容的方式进行定义(POSIX首先定义了它)

标题定义了类型。使用它的函数中有三个在中声明,另一个在
中声明:


当然,这些也是C17(C18)的一部分。您必须使用
-std=c11
或类似工具(GCC 9.2.0似乎可以识别
-std=c17
-std=c18
,以及
-std=c2x
来编译下一版本的标准),以便自动定义类型
结构时间规范。
将-D_GNU__源添加到CFLAG中也会起作用

gcc测试.c-o测试-std=c99-D_GNU_源

看看/usr/include/time.h。这是包装timespec定义的预处理器条件_GNU源支持使用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.  */
 }; 

这并不是他将-std=gnu89与-std=c99进行比较的问题的答案。更正确的比较应该是-std=gnu89到-std=gnu99。虽然我同意乔纳森的回答更好地解释了这里发生的事情,但对这个答案的反对票是完全没有根据的。它清楚地表明OP正在将
gnu89
c99
进行比较,这就是产生错误的原因,并表明
c89
也会产生相同的错误。这是有用的补充信息。如果您只需要POSIX,您应该将
\u POSIX\u C\u SOURCE
定义为正确的值
\u XOPEN\u SOURCE
是用于XSI扩展的。@R..:是的,你是学究式的正确。然而,实际上,您真的只想要POSIX而不想要XSI吗?如果是这样,您可以读取并设置POSIX。对于大多数人来说,大多数时候,给出的解决方案都是合理的。在最新的SUS中,几乎所有有价值的功能都被转移到了base,而XSI主要是遗留接口。当然,我说“大部分”是在掩饰自己<与
\u POSIX\u C\u SOURCE
相比,code>\XOPEN\u SOURCE确实带来了一些有用的东西,例如strdup()、strtime()、srandom()、realpath()、lockf()和一些大文件支持的东西。
/*
@(#)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 */
#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.  */
 };