简体   繁体   English

为什么 gcc/clang 处理代码略有不同? (给出的例子)

[英]Why does gcc/clang handle code slightly differently? (Example given)

So I was messing around with C code and I noticed something about the way that gcc and clang handle code.所以我在搞乱 C 代码,我注意到 gcc 和 clang 处理代码的方式。

If I declare an array in file scope using a variable size, clang compiles with no problem but gcc throws an error.如果我使用可变大小在文件 scope 中声明一个数组,则 clang 编译没有问题,但 gcc 会引发错误。 My guess is that it has to do with which compiler flags are/are not enabled by default in gcc/clang, but I would be glad if someone could tell me exactly why this thing is happening and maybe suggest some online resource where I can learn more about this functionality.我的猜测是,它与 gcc/clang 中默认启用/未启用哪些编译器标志有关,但如果有人能准确地告诉我为什么会发生这种情况并可能建议一些我可以学习的在线资源,我会很高兴有关此功能的更多信息。

Here is an arbitrary example of the code that throws the error -这是引发错误的代码的任意示例 -

typedef struct node{
    int data;
    struct node *next;
    struct node *prev;
}node;

const int N = 1000;
node *table[N]; // This is where the error is

int main() {
    return 0;

running clang example.c with no other flags compiles fine running gcc example.c with no other flags throws an error - running clang example.c with no other flags compiles fine running gcc example.c with no other flags throws an error -

example.c:9:7: error: variably modified 'table' at file scope
    9 | node *table[N];
      |       ^~~~

N looks like a constant, but it is not really. N看起来像一个常数,但实际上并非如此。 The const means « I swear that I won't change the value of this variable » (or the compiler will remind me.); const的意思是“我发誓我不会改变这个变量的值”(否则编译器会提醒我。); But it does not mean that it could not change by another mean I don't see in this compilation unit.但这并不意味着它不能以我在这个编译单元中看不到的另一种方式改变。 thus this is not exactly a constant.因此这并不完全是一个常数。

gcc seems to be very strict with the standard, but using the option -pedantic makes clang emit a warning. gcc似乎对标准非常严格,但使用选项-pedantic会使clang发出警告。

$ clang -o prog_c prog_c.c -pedantic
prog_c.c:12:14: warning: variable length array folded to constant array as an extension [-Wgnu-folding-constant]
double table[N];
             ^
1 warning generated.

$ clang -o prog_c prog_c.c -pedantic -std=c90
prog_c.c:12:13: warning: variable length arrays are a C99 feature [-Wvla-extension]
double table[N];
            ^
prog_c.c:12:8: warning: size of static array must be an integer constant expression [-Wpedantic]
double table[N];
       ^
2 warnings generated.

$ clang -o prog_c prog_c.c -pedantic -std=c99
prog_c.c:12:8: warning: size of static array must be an integer constant expression [-Wpedantic]
double table[N];
       ^
1 warning generated.

Depending on the version of gcc you are using, it defaults to C90 (with some extensions), and variable-length arrays are not a part of C90.根据您使用的gcc的版本,它默认为 C90(带有一些扩展),并且可变长度 arrays 不是 C90 的一部分。

If you specify -std=c99 or -std=c11 , it should support VLAs.如果您指定-std=c99-std=c11 ,它应该支持 VLA。

However, per the C language definition, VLAs cannot have static storage duration (as an array declared at file scope does).但是,根据 C 语言定义,VLA 不能具有static存储持续时间(就像在文件 scope 中声明的数组一样)。 So clang must be treating N as a constant expression (much like C++ does) and the array is fixed-length, not variable-length.所以clang必须将N视为常量表达式(很像 C++ 所做的),并且数组是固定长度的,而不是可变长度的。 So far I haven't found anything in the clang documentation that would indicate that, though.到目前为止,我还没有在clang文档中找到任何可以表明这一点的内容。

Run both compilers with the options -std=c11 -pedantic and see if you don't get the same errors.使用选项-std=c11 -pedantic运行两个编译器,看看是否没有得到相同的错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么 gcc -O3 处理 avx256 compare intrinsic 的方式不同于 gcc -O0 和 clang? - Why does gcc -O3 handle avx256 compare intrinsic differently than gcc -O0 and clang? 为什么GCC / Clang在不同情况下的初始化行为不同? - Why GCC/Clang behaves differently on initialization in different cases? 为什么 MSVC 预处理器连接令牌的方式与 GCC 和 Clang 不同? - Why is MSVC preprocessor concatenating tokens differently than GCC and Clang? 为什么GCC和Clang的结果与以下代码不同? - Why results of GCC and Clang are different with following code? 为什么clang与gcc不同,需要-lm? - Why does clang require -lm unlike gcc? 为什么GCC seg会在教科书上没有clang的情况下出错? - Why does GCC seg fault where clang does not on a textbook exercise? 为什么 gcc 和 clang 不对库函数的未使用结果发出警告? - Why does not gcc and clang warn for unused result of library functions? 为什么 clang 无法展开循环(即 gcc 展开)? - Why does clang is unable to unroll a loop (that gcc unrolls)? 为什么gcc / clang默认知道链接到libc? - Why does gcc/clang know to link to libc by default? 与gcc相比,为什么clang与寄存器变量表现得很奇怪? - Why does clang behave weirdly with register variables compared to gcc?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM