首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >GCC和-std=c99抱怨不知道结构

GCC和-std=c99抱怨不知道结构
EN

Stack Overflow用户
提问于 2010-10-06 17:20:00
回答 3查看 20.1K关注 0票数 43

当我试图用gcc -std=c99在Linux上编译它时,编译器抱怨不知道struct timespec。但是,如果我在没有-std=c99的情况下编译它,那么一切都可以正常工作。

代码语言:javascript
运行
复制
#include <time.h>

int main(void)
{
  struct timespec asdf;
  return 0;
}

为什么会这样,还有什么方法可以让它与-std=c99一起工作呢?

EN

回答 3

Stack Overflow用户

发布于 2010-10-06 17:24:00

显式启用POSIX功能

timespec来自POSIX,因此您必须“启用”POSIX定义:

代码语言:javascript
运行
复制
#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)的定义。

  • 如果您想要2008年POSIX (SUS v4)材料,请使用_XOPEN_SOURCE 700
  • 如果您想要POSIX 2004 (SUS v3)材料,请使用_XOPEN_SOURCE 600
  • 如果您想要POSIX 1995 (SUS v2,1997)材料,请使用_XOPEN_SOURCE 500

正如注释中所指出的,使用_XOPEN_SOURCE可以在严格的POSIX之上严格地启用XSI (X/Open )扩展,但是对于您来说,很少需要POSIX而不是XSI。您通常应该指定_XOPEN_SOURCE,而不是使用_POSIX_C_SOURCE指定futz。有关特性宏的更多信息,请参见编译环境上的(POSIX 2018)。

对于我2010年的系统,POSIX 2008并不像POSIX 2004那样广泛可用,所以这就是我所使用的--但是YMMV。请注意,SUS v3和v4都需要C99编译。至少在Solaris上,使用C89失败了。

GCC提供-std=gnuXX选项

如果您将-std=c11指定为GCC (或Clang仿真器),则只启用标准C定义。如果您使用-std=gnu11,那么POSIX和标准C的其他扩展在默认情况下是可见的。

请注意,GCC 4.x和更早版本默认使用了-std=gnu90 (对应于C90 +扩展)。GCC 5.x及以后默认使用-std=gnu11。在默认情况下,从来没有任何版本的GCC启用-std=gnu99

使用标头控制POSIX版本信息

我现在(2019年)使用一个头来封装这个信息,这样以后的更改只需要更改单个头,而不是每个使用POSIX特性的源文件。随着时间的推移,从多个源文件中编辑出旧的章节是痛苦的,而POSIX 2008变得流行起来。

代码语言:javascript
运行
复制
/*
@(#)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 */

您可以使用此标题的信息,而不需要堆栈溢出所使用的"CC by-sa 3.0“许可证所要求的归属和版权通知。此代码可在我的SOQ (堆栈溢出问题)存储库中作为文件posixver.h在GitHub的src/libsoq子目录中使用。

C11定义struct timespec

请注意,C11定义了struct timespec,并以与POSIX兼容的方式这样做(POSIX首先定义了它)。

标头定义类型。使用它的三个函数是在中声明的,另一个是在<time.h>中声明的。

当然,这些也是C17 (C18)的一部分。您必须使用-std=c11或类似的语言(GCC 9.2.0似乎同时识别了-std=c17-std=c18,以及标准的下一个版本的-std=c2x )来自动定义struct timespec类型。

票数 62
EN

Stack Overflow用户

发布于 2010-10-06 17:22:57

我建议使用-std=gnu99进行编译。

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

代码语言:javascript
运行
复制
#include <time.h>

int main() {
    struct timespec asdf;
    return 0;
}
代码语言:javascript
运行
复制
[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
票数 40
EN

Stack Overflow用户

发布于 2019-12-02 11:03:26

将-D_GNU_SOURCE添加到您的CFLAGS中也是有效的。

gcc测试.c -o -std=c99 -D_GNU_SOURCE

查看/usr/include/time.h。这是包装timespec定义的预处理条件。_GNU_SOURCE启用__USE_POSIX199309。

代码语言:javascript
运行
复制
#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.  */
 }; 
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3875197

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档