简体   繁体   English

使用gcc,严格包含C99符号,特别是不包括POSIX

[英]With gcc, include strictly C99 symbols, specifically excluding POSIX

I am taking a course in C after many years programming. 经过多年的编程,我正在修课。 My instructor is not using a POSIX machine, and I was recently penalized for using the index function in an assignment. 我的教练没有使用POSIX机器,最近我因在作业中使用index功能而受到处罚。 I did some research and I notice that while index was an early part of AT&T Unix and is POSIX-compliant, it is not part of the C99 standard. 我做了一些研究,我注意到虽然index是AT&T Unix的早期部分,并且符合POSIX标准,但它不是C99标准的一部分。 I'd like gcc to help me find use of similar symbols . 我希望gcc帮我找到类似符号的用法 I am compiling on OSX with gcc 4.2 ( not llvm) 我正在使用gcc 4.2( 不是 llvm)编译OSX

My first leg of research involved noticing that my string.h file wraps the prototype for index in the following check for feature test macros: 我的第一站研究涉及注意我的string.h文件在下面的特征测试宏检查中包装了index的原型:

#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)

After a little digging, I found this (in my /usr/include/sys/cdefs.h ): 经过一番挖掘,我发现了这个(在我的/usr/include/sys/cdefs.h ):

 /* STRICT  Defining _POSIX_C_SOURCE or _XOPEN_SOURCE restricts the
 *      available APIs to exactly the set of APIs defined by the
 *      corresponding standard, based on the value defined.
 *
 *      A correct, portable definition for _POSIX_C_SOURCE is 200112L.
 *      A correct, portable definition for _XOPEN_SOURCE is 600L.
 */

And so with this gcc command: 所以使用这个gcc命令:

gcc -D _POSIX_C_SOURCE=200112L -pedantic -Wall -std=c99 -o myExec ./mySource.c

I do get a decent warning: 得到一个体面的警告:

warning: incompatible implicit declaration of built-in function ‘index’

This confuses me, and I want to make the program fail to link as well. 这混淆了我我想使程序无法和链接。 The reason it confuses me is, I read at opengroup.org that defining that macro should expose POSIX symbols, not hide them. 它让我困惑的原因是,我在opengroup.org上读到 ,定义该宏应该暴露 POSIX符号,而不是隐藏它们。 So here is my question in a succinct form: 所以这是我的问题,简洁的形式:

How can I make gcc 4.2 (on OSX 10.6) compile and link my program in an environment which is strictly C99 with no additional symbols available? 如何制作gcc 4.2(在OSX 10.6上)在一个严格的 C99环境中编译和链接我的程序, 没有其他符号可用?

Ideally, I want warnings during compile and failure to link . 理想情况下,我希望在编译期间发出警告并且无法链接 I'm hoping that the answer does not involve telling gcc that I am writing POSIX code, when I believe that's the opposite of what I want to tell it. 我希望答案不涉及告诉gcc我正在编写POSIX代码,当我认为这与我想说的相反时。 What am I not understanding? 我不明白的是什么?

  1. You're not going to get a link error, sorry. 抱歉,你不会收到链接错误。 Libraries don't work that way. 图书馆不这样做。 The index function is a part of the standard library. index函数标准库的一部分。 The standard library supports multiple versions of C (and POSIX) at the same time, and the macros select which prototypes get exposed. 标准库同时支持多个版本的C(和POSIX),宏选择暴露哪些原型。

  2. The -ansi flag is equivalent to -std=c89 , so stop doing that. -ansi标志等同于-std=c89 ,所以停止这样做。

  3. You are right that _POSIX_C_SOURCE exposes additional functionality, but it also specifies which version of the functionality to expose. 你是对的_POSIX_C_SOURCE公开了其他功能,但它也指定了要公开的功能版本 Defining _POSIX_C_SOURCE=200112L means that index appears in <strings.h> instead of <string.h> . 定义_POSIX_C_SOURCE=200112L意味着index出现在<strings.h>而不是<string.h> It's still there. 它还在那里。 Specifying the 2008 POSIX will get rid of index entirely, since it was removed from later versions of the POSIX standard. 指定2008 POSIX将完全摆脱index ,因为它已从更高版本的POSIX标准中删除。

  4. There is a macro which means "only ANSI C", and that is _ANSI_SOURCE . 这意味着“仅ANSI C”的宏,那就是_ANSI_SOURCE

  5. You can get a compilation error (but not a link error) by adding -Werror-implicit-function-declaration . 您可以通过添加-Werror-implicit-function-declaration来获取编译错误(但不是链接错误)。

$ gcc -Werror-implicit-function-declaration \
    -D_ANSI_SOURCE -pedantic -Wall -std=c99 ...
error: implicit declaration of function 'index'

This seems to work just fine on all combinations OS X 10.5/10.8, GCC 4.0/4.2. 这似乎适用于OS X 10.5 / 10.8,GCC 4.0 / 4.2的所有组合。

To obtain a C99 environment, pass the flags -std=c99 -pedantic to gcc. 要获得C99环境,请将标志-std=c99 -pedantic给gcc。 This should not define any additional feature-test macros. 这不应该定义任何其他功能测试宏。

Note however that this is only omits the declarations , because those invade the C99 programmer-reserved namespace. 但请注意,这只是省略了声明 ,因为它们会侵入C99程序员保留的命名空间。 The actual symbols are still likely to be available - those shouldn't affect the compilation of a correct C99 program because they tend to be "weak" symbols, but they won't force an error if you declare them yourself and use them. 实际的符号仍然可能可用 - 这些符号不应该影响正确的C99程序的编译,因为它们往往是“弱”符号,但如果您自己声明并使用它们,它们不会强制出错。

For the record: with icc I found it most helpful to do 为了记录:使用icc我发现它最有帮助

icc -no-gcc -diag-enable port-win -fabi-version=2 -std=c99 ...

which will skip all gcc specific voodoo in the system header files and warn about POSIXisms that don't exist on windows. 这将跳过系统头文件中所有gcc特定的voodoo,并警告Windows上不存在的POSIXisms。

As for throwing an error, I'd just use -Werror . 至于抛出错误,我只使用-Werror

Unfortunately, gcc can't turn off gnu-specific attribute processing in system header files. 不幸的是,gcc无法关闭系统头文件中特定于gnu的属性处理。 And, even more unfortunate, the stated gcc version does not support the -Werror=<diagnostic> syntax to throw errors upon certain warnings only. 而且,更不幸的是,声明的gcc版本不支持-Werror=<diagnostic>语法,仅在某些警告时抛出错误。

So in essence, the combination of compiler and version you state can't really help you with what you want. 所以从本质上讲,你声明的编译器和版本的组合并不能真正帮助你实现你想要的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM