"初始化器元素不是常数QUOT;错误在Linux中GCC没有理由,编译C [英] "Initializer element is not constant" error for no reason in Linux GCC, compiling C

查看:749
本文介绍了"初始化器元素不是常数QUOT;错误在Linux中GCC没有理由,编译C的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我把我的main.c文件,并在Mac OS X的gcc -std = C1X -c main.c中编译它,它工​​作正常,没有错误。然后,我做LinuxMint并在树莓派同样的事情,而在这两种情况下,它给了我关于初始元素不是常量的错误。

I take my main.c file and compile it with gcc -std=c1x -c main.c in Mac OS X, and it works fine with no errors. Then I do the exact same thing in LinuxMint and on a Raspberry Pi, and in both cases, it gives me errors about "initializer element is not constant".

相关code有问题的线的一个例子:

One example of a problematic line with relevant code:

//STATIC GLOBAL CONSTANTS
const unsigned long long LATITUDE = (long) 3600000;
const unsigned long long LONGITUDE = (long) 1810000;
const unsigned long long MAX_COORDINATES_NUMBER = (LATITUDE-1) + LATITUDE*(LONGITUDE-1); //compiler error: initializer element is not constant

这应该让我做算术题,对不对?我可以只更换与实际数字,它的工作,但它会成为混乱。和它的作品在我的Mac罚款反正。是否有一些GCC选项我必须指定在Linux(除-std = C1X,你也不需要在Mac)?

It's supposed to let me do arithmetic, right? I could just replace that with the actual numbers, and it would work, but then it would become messy. And it works fine on my Mac anyway. Is there some option in GCC I have to specify on Linux (besides -std=c1x, which you also don't need on Mac)?

推荐答案

C语言需要一个静态对象初始化是一个恒定的前pression。 (由于静态对象的初始化发生之前开始,没有发生任何运行时评估的情况发生。)

The C language requires the initializer for a static object to be a constant expression. (Since initialization of static objects occurs before main begins, there's no place for any run-time evaluation to happen.)

C'S 常量关键字并不意味着常量,虽然字有明显的关系。 A 恒前pression 的是一个就可以了,而且在某些情况下,必须在编译时,评估。 常量表示只读。例如,在块范围(在函数定义内),这样:

C's const keyword does not mean "constant", though the words are obviously related. A constant expression is one that can be, and in some cases must be, evaluated at compile time. const means read-only. For example, at block scope (inside a function definition), this:

const int r = rand();

是完全合法的。显然,初始化不能在编译时进行评估;在常量仅仅意味着研究它已经initalized后,不得修改。

is perfectly legal. Obviously the initializer can't be evaluated at compile time; the const merely means that r may not be modified after it's been initalized.

当你写的:

const unsigned long long LATITUDE = (long) 3600000;

LATITUDE 一提的是不是一个常量前pression。编译器肯定的可能的评价在编译的时候这样的参考,但C标准不要求它。 (恒定和非恒定的前pressions之间的线路不得不被某处绘制,和语言的作者选择,使区分相对简单,具有一些特殊情况。)

a reference to LATITUDE is not a constant expression. A compiler certainly could evaluate such a reference at compile time, but the C standard doesn't require it to. (The line between constant and non-constant expressions had to be drawn somewhere, and the authors of the language chose to make the distinction relatively simple, with few special cases.)

现在这当然不错,C语言的可能的已定义,这样 LATITUDE 是一个常量前pression。这是C ++,并且我认为对C采用类似的规则。但在当前的C规则,这不是,这意味着你不能在初始化使用 LATITUDE 的静态对象。

Now it's certainly true that the C language could have been defined so that LATITUDE is a constant expression. It is in C++, and I've argued for C to adopt a similar rule. But under current C rules, it's not, which means that you can't use LATITUDE in the initializer for a static object.

这也意味着,(编译器,按我的理解,是一个调用,当你键入 GCC 的MacOS下)是很可能的非共形,因为它不能诊断该错误。在我自己的Linux系统,我发现,当与 -std = C11 -pedantic 调用,GCC 4.7.2正确诊断的错误,但铛3.4没有。

This also means that clang (the compiler that, as I understand it, is the one invoked when you type gcc under MacOS) is very likely non-conforming, because it fails to diagnose this error. On my own Linux system, I find that, when invoked with -std=c11 -pedantic, gcc 4.7.2 correctly diagnoses the error, but clang 3.4 does not.

除的也许的从6.6节的2011 ISO C标准的第10段(也存在于1990年和1999年标准)本条款:

Except perhaps for this clause from section 6.6 paragraph 10 of the 2011 ISO C standard (which also exists in the 1990 and 1999 standards):

这是实现可能接受其它形式不断前pressions的。

An implementation may accept other forms of constant expressions.

这是可以想象的铿锵接受 LATITUDE 作为一个恒定的前pression,因为它需要这个权限的优势 - 但是我仍然期望至少一个警告从铛-std = C11 -pedantic -Wall -Wextra ,有没有。

It's conceivable that clang accepts LATITUDE as a constant expression because it takes advantage of this permission -- but then I'd still expect at least a warning from clang -std=c11 -pedantic -Wall -Wextra, and there is none.

更新:当我编译如下:

#include <stdio.h>

const unsigned long long LATITUDE = (long) 3600000;

int main(void) {
    switch (0) {
        case LATITUDE:
            puts("wrong");
            break;
        default:
            puts("ok(?)");
            break;
    }
}

与选项铛3.0 -std = C99 -pedantic ,我得到:

c.c:7:14: warning: expression is not integer constant expression (but is allowed as an extension) [-pedantic]
        case LATITUDE:
             ^~~~~~~~
1 warning generated.

铿锵3.4,该警告是:

With clang 3.4, the warning is:

c.c:7:14: warning: expression is not an integer constant expression; folding it to a constant is a GNU extension [-Wgnu-folding-constant]
        case LATITUDE:
             ^~~~~~~~
1 warning generated.

所以铛识别到它不是一个恒定的前pression;该错误是,它不发出警告的声明 MAX_COORDINATES_NUMBER

这篇关于&QUOT;初始化器元素不是常数QUOT;错误在Linux中GCC没有理由,编译C的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆