1

我在 Xcode 中创建了一个基本的 C 项目,并稍微修改了 main.c 中的起始代码。我还进入了构建设置并告诉它使用 ANSI-C。这是我的代码:

int main(int argc, const char * argv[])
{
    // a statement!
    printf("Hello, World!\n");

    // shouldn't this cause a compiler error?
    // the variable isn't declared at the top of the scope.
    int x;
    x += 10;

    return 0;
}

显然,它没有多大作用,但我预计变量声明会产生编译器错误(因为旧版本的 C 需要在作用域的开头,在其他语句之前声明变量)。然而,Xcode 愉快地编译并运行它,既没有错误也没有警告。

我可能在某个地方犯了一个愚蠢的错误,但我试图理解为什么这段代码可以编译。我读过 C99 和 C11 允许您在任何地方声明变量,所以这会起作用,但我明确地将项目设置为使用 ANSI-C。这只是 Apple 的 LLVM 编译器的工作方式吗?还是我在其他地方错过了什么?

4

1 回答 1

4

TL;DR您需要添加-pedantic(或-Wdeclaration-after-statement)以-ansi获取所需的警告。

令我惊讶的是,clang(来自 Apple XCode 7.2)和gcc(来自我构建的 GCC 5.3.0)在编译时都接受代码,-std=c90或者-ansi即使它不严格符合 C90。

但是,当被告知要这样做时,双方都抱怨-pedantic

$ clang -ansi -c xyz.c
$ clang -std=c90 -c xyz.c
$ gcc -std=c90 -c xyz.c
$ which gcc
/opt/gcc/v5.3.0/bin/gcc
$ gcc -std=c90 -pedantic -c xyz.c
xyz.c: In function ‘main’:
xyz.c:7:5: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
     int x;
     ^
$ clang -pedantic -std=c90 -c xyz.c
xyz.c:7:9: warning: ISO C90 forbids mixing declarations and code [-Wdeclaration-after-statement]
    int x;
        ^
1 warning generated.
$ clang -pedantic -ansi -c xyz.c
xyz.c:7:9: warning: ISO C90 forbids mixing declarations and code [-Wdeclaration-after-statement]
    int x;
        ^
1 warning generated.
$

该文件xyz.c是您的源代码,注释被剥离,#include <stdio.h>添加在顶部,并int main(void)代替,int main(int argc, char **argv)因为代码不使用参数。

请注意,您的代码具有未定义的行为;增加一个未初始化的变量是个坏主意。

于 2016-01-02T01:08:54.760 回答