强制编译器符合C99标准

9

当我在编写我的项目时,我发现我已经使用了一段时间的匿名结构体实际上只有在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模式,但很明显这并不起作用(除了gcc 4.1可以在没有-std参数的情况下编译)。 所以我的问题是,如何强制编译器gcc和clang,在任何版本中,如果我编写的代码不符合使用-std指定的标准,则发出错误信息?是否有一些我不知道的命令行参数?


这个 Stack Overflow 的帖子对你有用吗?https://dev59.com/1nI95IYBdhLWcg3wsQL9 - miushock
@miushock 谢谢,但是不行,这也没有帮助。使用 c99 代替 gcc 仍然可以编译通过,而它本应该失败... - grasbueschel
1
我认为可能需要使用-pedantic标志来警告语言扩展(GNU C在C99中有匿名结构体)。也许这个关于/usr/bin/c99的答案对你有用。 - MBlanc
@MBlanc 就是这样!使用 -pedantic,我得到了一个警告,说我使用了非 C99 特性。由于这只是一个警告,它仍然可以编译,但这比没有好(希望它是一个错误)。请将此评论再次发布为答案,我很乐意接受!谢谢! - grasbueschel
1
@grasbueschel 你可以添加 -Werror 标志将(所有)警告变成错误。 - Kninnug
显示剩余2条评论
2个回答

20

-std=c99 不会禁用语言扩展(GNU C在C99中支持匿名结构体)。

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


10

无论是 gcc 还是 clang ,都允许使用大量扩展,而clang的这里。总的来说,clang 试图支持大多数 gcc 的扩展。例如,两者甚至允许您在 C++ 中使用仅适用于 C 的功能,比如 VLA(C99特性)

在这种情况下,无论是 gcc 还是 clang 都允许您在 C99 模式下使用未命名结构/联合字段,即使它是一个C11 特性。

GCC支持的语言标准文档清楚地说明了需要哪些标志才能将它们转换为警告和错误,据我所知,clang 遵循相同的约定:

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

因此,-pedantic 会在您使用扩展时发出警告,-pedantic-errors 会将这些警告变成错误。使用 -pedantic 标志,您应该在 gcc 中看到类似于以下内容的警告:

warning: ISO C99 doesn't support unnamed structs/unions [-Wpedantic]

clang 中会看到如下警告(现场查看):

warning: anonymous structs are a C11 extension [-Wc11-extensions]

加上 -pedantic-errors 后会出现错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接