对于gcc,严格包括C99符号,特别是不包括POSIX
经过多年编程,我正在学习C语言课程。我的指导老师没有使用POSIX机器,我最近因为在作业中使用对于gcc,严格包括C99符号,特别是不包括POSIX,c,macos,gcc,compiler-construction,linker,C,Macos,Gcc,Compiler Construction,Linker,经过多年编程,我正在学习C语言课程。我的指导老师没有使用POSIX机器,我最近因为在作业中使用index函数而受到处罚。我做了一些研究,发现虽然index是AT&T Unix的早期部分,并且与POSIX兼容,但它不是C99标准的一部分。我希望gcc能帮助我找到类似符号的用法。我使用GCC4.2(不是llvm)在OSX上编译 我的第一步研究是注意到我的string.h文件在下面的特性测试宏检查中为索引封装了原型: #if !defined(_POSIX_C_SOURCE) || defined(_
index
函数而受到处罚。我做了一些研究,发现虽然index
是AT&T Unix的早期部分,并且与POSIX兼容,但它不是C99标准的一部分。我希望gcc能帮助我找到类似符号的用法。我使用GCC4.2(不是llvm)在OSX上编译
我的第一步研究是注意到我的string.h文件在下面的特性测试宏检查中为索引
封装了原型:
#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
经过一番挖掘,我发现了这个(在我的/usr/include/sys/cdefs.h
中):
因此,使用这个gcc命令:
gcc -D _POSIX_C_SOURCE=200112L -pedantic -Wall -std=c99 -o myExec ./mySource.c
我确实得到了一个很好的警告:
warning: incompatible implicit declaration of built-in function ‘index’
这让我困惑,我想让程序也无法链接。它让我困惑的原因是,我读到定义宏应该暴露POSIX符号,而不是隐藏它们。我的问题很简单:
如何使gcc 4.2(在OSX 10.6上)在一个严格的C99环境中编译和链接我的程序,而没有其他可用的符号?
理想情况下,我希望编译和链接失败时出现警告。我希望答案不涉及告诉gcc我正在编写POSIX代码,而我认为这与我想要告诉它的相反。我不明白什么?要获得C99环境,请将标志
-std=C99-pedantic
传递给gcc。这不应定义任何其他功能测试宏
但是请注意,这只是忽略声明,因为这些声明会侵入C99程序员保留的命名空间。实际符号仍然可能可用-这些符号不应影响正确C99程序的编译,因为它们往往是“弱”符号,但如果您自己声明并使用它们,它们不会强制出错。请注意:对于
icc
,我发现这样做最有帮助
icc -no-gcc -diag-enable port-win -fabi-version=2 -std=c99 ...
这将跳过系统头文件中所有特定于gcc的巫毒,并警告windows上不存在的偏斜
至于抛出错误,我只使用-Werror
不幸的是,gcc无法在系统头文件中关闭gnu特定的属性处理。而且,更不幸的是,声明的gcc版本不支持仅在某些警告时抛出错误的-Werror=
语法
因此,本质上,编译器和您声明的版本的组合并不能真正帮助您实现所需的功能
索引
函数是标准库的一部分。标准库同时支持多个版本的C(和POSIX),宏选择要公开的原型-ansi
标志等同于-std=c89
,因此停止这样做\u POSIX\u C\u SOURCE
公开了其他功能,但它也指定了要公开的功能版本。定义\u POSIX\u C\u SOURCE=200112L
意味着索引将出现在
中,而不是
中。它还在那里。指定2008 POSIX将完全摆脱索引
,因为它是从POSIX标准的更高版本中删除的
\u ANSI\u SOURCE
-Werror隐式函数声明
,可以获得编译错误(但不是链接错误)这似乎在所有OS X 10.5/10.8、GCC 4.0/4.2的组合上都能正常工作。很抱歉一开始就忽略了它(我编辑了我的问题以表明这一点),但我一直在使用这些标志;它们不会导致警告(没有POSIX feature宏),也不会导致链接失败(即使使用宏),您真的坚持GCC4.2吗?因为这甚至不完全符合C99本身。叮当声可能是更好的选择。不,绝对不是!我愿意尝试新的编译器(我已经在其他项目的较新OSX上使用了clang/llvm)。也许我明天会对此进行报道。
index
并不完全符合POSIX标准。它在POSIX 2008中被删除,在POSIX 2001中已经被弃用。问题可能是指定了-ansi
和-std=c99
<代码>-ansi等同于指定-std=c89
。当要求gcc遵守两个不同的标准时,我不确定gcc的行为,但-ansi
和-std=c99
似乎是相互排斥的选项。@谢谢,眼光好(尝试了许多选项的证据)。如果我正确地理解了许多GNU工具,那么使用相互矛盾的含义指定多个标志通常只需遵循最后一个就可以解决。尽管我将删除-ansi(并在编辑文章之前验证结果是否相同)-Werror隐式函数声明
至少与GCC 4.0.ah一样旧,我明白了,我指的是新语法:-Werror=隐式函数声明,…
+1-一个实用方法的精妙总结,它将涵盖大多数非ISO C功能(这可能足以满足ctrahey的需求),这是一个很好的答案!我不知道\u ANSI\u SOURCE
。回答得很好,谢谢!就我的目的而言,这很好:-)有\u ISOC99\u源代码
,有什么不同?
icc -no-gcc -diag-enable port-win -fabi-version=2 -std=c99 ...
$ gcc -Werror-implicit-function-declaration \
-D_ANSI_SOURCE -pedantic -Wall -std=c99 ...
error: implicit declaration of function 'index'