为什么 Xcode 允许我在任何地方声明 C 变量?

Why is Xcode allowing me to declare C variables anywhere?

我在 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 编译器的工作方式吗?还是我在其他地方遗漏了什么?

TL;DR 您需要将 -pedantic(或 -Wdeclaration-after-statement)添加到 -ansi 以获得您想要的警告。

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

然而,当被告知 -pedantic 时,两者都会抱怨 -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),因为代码没有不要使用参数。

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