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

时间:2016-01-02 00:38:27

标签: c ansi-c

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

1 个答案:

答案 0 :(得分:3)

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),因为代码不使用争论。

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