当我发现我已经使用了一段时间的匿名结构实际上只能在C11中使用,而不是C99时,我正在对我的项目进行编码,这是我想编写的标准.
给出以下代码:
struct data { int a; struct { int b; int c; }; }; int main() { struct data d; d.a = 0; d.b = 1; d.c = 2; return 0; }
此代码应仅在C11中编译(或者如果编译器扩展提供此功能并且已启用).那么让我们看看不同编译器的结果:
compiler: Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn) Target: x86_64-apple-darwin13.1.0 Thread model: posix command: clang -std=c99 -Wall test.c -o test result: **OK**
compiler: gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-54) command: gcc -std=c99 -Wall test.c -o test result: **NOT OK** test.c:6: warning: declaration does not declare anything test.c: In function 'main': test.c:14: error: 'struct data' has no member named 'b' test.c:15: error: 'struct data' has no member named 'c'
compiler: gcc (GCC) 4.7.2 20121109 (Red Hat 4.7.2-8) command: gcc -std=c99 -Wall test.c -o test result: **OK** test.c: In function 'main': test.c:11:14: warning: variable 'd' set but not used [-Wunused-but-set-variable]
我一直试图通过指定强制编译器进入C99模式-std=c99
,但显然这不起作用(除了没有-std参数编译好的gcc 4.1).所以现在我的问题是,如果我编写的代码不符合我指定的标准,我怎么能强制编译器gcc和clang在任何版本中发出错误-std
?是否有一些我不知道的命令行参数?
双方gcc
并clang
允许大量的扩展和这里铿锵.clang
通常尝试支持大多数扩展gcc
.双方甚至会允许你使用那些功能Ç只在C++例如VLAS这是C99的功能.
在这种情况下,两者都允许您在C99模式下的结构/联合中使用未命名的struct/union字段,即使它是C11功能.
GCC支持的语言标准很好地记录了将这些变成警告和错误所需的标志,据我所知clang
遵循相同的约定:
[...]要获得标准所需的所有诊断,您还应指定-pedantic(或-pedantic-errors,如果您希望它们是错误而不是警告).[...]
因此-pedantic
,如果您使用扩展程序并将-pedantic-errors
这些警告变为错误,则会发出警告.有了-pedantic
标志你应该看到这样的警告gcc
:
警告:ISO C99不支持未命名的结构/联合[-Wpedantic]
而这clang
(见直播):
警告:匿名结构是C11扩展名[-Wc11-extensions]
它变成了一个错误-pedantic-errors
.
-std=c99
不会禁用语言扩展(GNU C在C99中有一个结构).
该-pedantic
(或-pedantic-errors
)标志使编译器警告语言扩展.