【问题标题】:Forcing compiler to C99 standard强制编译器符合 C99 标准
【发布时间】:2014-04-12 15:55:27
【问题描述】:

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

叮当声 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 参数的情况下可以正常编译)。 所以我现在的问题是,如果我编写的代码不符合我使用-std 指定的标准,如何强制编译器 gcc 和 clang 在任何版本中发出错误?是否有一些我不知道的命令行参数?

【问题讨论】:

  • 这个 SO 线程对你有什么帮助吗?stackoverflow.com/questions/2193634/setting-std-c99-flag-in-gcc
  • @miushock 谢谢,但不,这也无济于事。使用c99 而不是gcc 仍然会在它应该失败的地方编译...
  • 我相信需要-pedantic 标志可能来警告语言扩展(GNU C 在 C99 中有匿名结构)。也许这个关于/usr/bin/c99 的答案对你有用。
  • @MBlanc 就是这样!使用 -pedantic 我收到警告说我使用了非 C99 功能。由于它是一个警告,它仍然可以编译,但这总比没有好(希望我是一个错误)。再次发布此评论作为答案,我很乐意接受!谢谢!
  • @grasbueschel 您可以添加-Werror 标志以将(所有)警告转化为错误

标签: c gcc clang c99 c11


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    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的错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-27
      • 1970-01-01
      • 2019-12-16
      相关资源
      最近更新 更多