您的位置:首页 > 编程语言 > C语言/C++

C C++全局变量初始化 initializer element is not constant 错误

2013-06-08 15:48 447 查看


C C++全局变量初始化 initializer element is not constant 错误 c++中为什么不能对全局变量在函数外赋值


http://blog.csdn.net/abc78400123/article/details/6766947

分类: C语言基础2011-09-11
09:28 595人阅读 评论(0) 收藏 举报
c++c编译器initializationconstraintssemantic

***(行号):error: initializer element is not constant

***(行号):error: (near initialization for `**')
c标准:全局变量(external variable)和静态变量 (static variable)的初始化式必须为常量表达式

在C++中对于以下语句:

// 全局域

int i = 3;

int j = i;

编译时将i 放入.data 段,设置其值为3.

而对于j ,编译器遇到这种语句,只知道j = i ,由于 i 是变量,不是常量,编译器无法在编译时直接得到它的值,编译器只会找到i 的地址, 然后读取这个地址的内容,再把这个内容写入 j 的地址。编译器不能够直接用3 来初始化 j ,因为计算机不是人,不懂简单的人类逻辑,我们想“因为 i = 3,而 j = i,所以j = 3",而计算机无法在逻辑上由i = 3 和 j = i 来推出j = 3,就好像图灵机不可能证明某个论题的真伪一样。计算机只会“取 i 的地址,把3 放到 i 的地址中,取 i 的地址,读取这个地址中的内容,取
j 的地址,把这个内容 写入j 的地址。” 它不会思考,不懂因果,只是机械地执行指令。编译器无法在编译时求得一个非常量的值,它只能在运行时通过读取变量地址来间接得到变量的值,而全局变量在编译时就必须确定其值,故C有静态存储区数据必须用常量初始化的规定。在编译时只能用常量去初始化一个静态存储区的数据,而不能用“读取某个变量的内容”来初始化,所以编译器会将j 放入 .bss段,默认值为0 ,然后添加一条语句在运行时读取i 的值,再赋给j。这条语句在调用main()之前完成。

今天师弟的一个问题
//错误代码
node *p;
p = new node;
int main(void)
{…}
//修改后
node *p = new node;
int main(void)
{…}
找了好久不知道什么错误,我虽然很快帮他修改正确了,但却不明白其实质
查了好久,可能有点专牛角尖,是关于c c++全局变量赋值的问题,同时也关系到初始化和赋值的关系等
http://topic.csdn.net/u/20090129/19/d8661d27-4790-46cb-a424-c4fc8f7e28b4.html

这个帖子讨论了下c语言中全局变量的初始化

//test.c

char * p1 = (char *) malloc(10); //出现 initializer element is not constant错误

int main(void)

{

...

}

这个的原因已经弄明白,应该是C标准没有弄清楚,在c99中指明全局变量和static变量的初始化式必须为常量表达式,因此类似这样的情况也是有错误(VC和gcc下测试)

//test.c

int a = 1;

int b = a;

int main(void)

{

....

}

或者
//test.c

int main(void)

{

int a = 1;

static int b = a;

}
出现的错误都是initializer element is not constant,即初始值不是常量

上面是c语言的
c99标准描述如下:

C99标准 6.7.8 Initialization 第4款:

4 All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals.
关于 static storage duration:

C99 6.2.4 Storage durations of objects 第3款:

3 An object whose identifier is declared with external or internal linkage, or with the

storage-class specifier static has static storage duration. Its lifetime is the entire

execution of the program and its stored value is initialized only once, prior to program startup.
关于复杂类型 (比如struct):

C99 6.5.2.5 Compound literals 第7款:

7 All the semantic rules and constraints for initializer lists in 6.7.8 are applicable to

compound literals.

(参考 http://bbs.chinaunix.net/viewthread.php?tid=1275329&extra=&page=5 帖子
问题类似)
在c++中,编译器可能有所改进,上面的几个问题基本已经没有

可参考下这个帖子,关于全局变量初始化的:http://blogold.chinaunix.net/u1/41728/showart_347212.html
c、c++全局变量的赋值要在函数内部进行!
看下面测试例子:
int a;
a = 10; //这里是对全局变量进行赋值操作,是错误的
int main(void)
{

}
例如下面这个帖子:
http://topic.csdn.net/u/20100616/10/3823436c-f19c-40f0-9053-374f58c56d11.html
类似这样的情况也是不可以的:

printf(“hellow/n”);

int main(void)
{…}

总结下:
1、c语言中全局变量和static变量的初始化需要指定一个常量,不能是一个非常量的表达式;而在c++中是可以的
2、在操作c和c++全局变量时,只能对其采用初始化的方式,而不能采用赋值的方式,即可以
int a = 10; //错误
而不可以:
int a;
a = 10;
这应该是一个菜鸟级的问题,o(︶︿︶)o 自己还是太嫩了啊~~~

参考资料有:
http://blog.csdn.net/lychee007/archive/2010/04/08/5462764.aspx
http://topic.csdn.net/u/20091020/18/a8643fa1-6586-4a71-8518-95d88ec6b399.html
http://bbs.chinaunix.net/viewthread.php?tid=1275329&extra=&page=5
http://topic.csdn.net/u/20100616/10/3823436c-f19c-40f0-9053-374f58c56d11.html
http://blogold.chinaunix.net/u1/41728/showart_347212.html
http://webservices.ctocio.com.cn/net/405/9158905.shtml
http://www.cnblogs.com/chio/archive/2008/10/06/1305145.html
http://my.chinaunix.net/space.php?uid=25311153&do=blog&id=117951
http://zhidao.baidu.com/question/137062995
http://bbs.chinaunix.net/thread-1285396-1-1.html



http://bbs.chinaunix.net/thread-1285396-1-1.html

http://topic.csdn.net/u/20090129/19/d8661d27-4790-46cb-a424-c4fc8f7e28b4.html

http://blog.csdn.net/jiqiren007/article/details/6213778
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: