强制编译器符合C99标准

时间:2014-03-09 16:51:51

标签: c gcc clang c99 c11

当我发现我已经使用了一段时间的匿名结构实际上只能在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中编译(或者如果编译器扩展提供此功能并且已启用)。那么让我们看看不同编译器的结果:

clang 5

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**

gcc 4.1

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'

gcc 4.7

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]

我总是试图通过指定-std=c99来强制编译器进入C99模式,但显然这不起作用(除了没有-std参数编译好的gcc 4.1)。 所以现在我的问题是,如果我编写的代码不符合我使用-std指定的标准,我怎么能强制编译器gcc和clang在任何版本中发出错误?是否有一些我不知道的命令行参数?

2 个答案:

答案 0 :(得分:15)

-std=c99不会禁用语言扩展(GNU C在C99中有结构)。

-pedantic(或-pedantic-errors)标志使编译器对语言扩展发出警告。

答案 1 :(得分:8)

gccclang都允许large number of extensionhere for clangclang通常会尝试支持gcc所做的大多数扩展。两者都允许您仅在 C ++ 中使用 C 的功能,例如VLAs which are a C99 feature

在这种情况下,两者都允许您在 C99 模式下使用Unnamed struct/union fields within structs/unions,即使它是 C11 功能。

Language Standards Supported by GCC很好地记录了将这些变成警告和错误所需的标志,据我所知clang遵循相同的约定:

  

[...]要获得标准所需的所有诊断,您还应该指定-pedantic(或-pedantic-errors,如果您希望它们是错误而不是警告)。 [...]

因此,-pedantic会在您使用附加信息时发出警告,-pedantic-errors会将这些警告变为错误。使用-pedantic标记,您应该在gcc中看到类似的警告:

  

警告:ISO C99不支持未命名的结构/联合[-Wpedantic]

这在clang see it live )中:

  

警告:匿名结构是C11扩展名[-Wc11-extensions]

并且-pedantic-errors会变成错误。