不寻常的行为
Unusual behaviour
为什么这段代码不能编译
#include <stdio.h>
int x=5;
int a[x];
int main()
{
a[0]=5;
printf("%dn",a[0]);
return 0;
}
当使用gcc filename.c -Wall -ansi -pedantic编译时,会产生一个错误
错误:变量修改' a '
然而,这段代码虽然会给出警告,但会给出正确的输出:
#include <stdio.h>
int main()
{
int x=5;
int a[x];
a[0]=5;
printf("%dn",a[0]);
return 0;
}
警告:ISO C90禁止可变长度数组' a ' [-Wvla]
但是,如果我尝试使用g++ filename.c -Wall -ansi -pedantic编译它,它会产生没有警告并且给出正确的输出
#include <stdio.h>
const int x=5;
int a[x];
int main()
{
a[0]=5;
printf("%dn",a[0]);
return 0;
}
我使用的是gcc版本4.7.0
请详细解释一下发生了什么事
在C中(与c++不同),const声明不产生常量表达式,即在C中,你不能在非vla数组声明中使用const int对象作为数组大小。
,
const int max_foos = 10;
int foos[max_foos];
在c++中有效,但在C中无效。
#define MAX_FOOS 10
int foos[MAX_FOOS];
注意:
const在c语言中并不意味着常量。
注意,可变长度数组仅在C99年才成为C标准的一部分,在此之前,标准不允许它们,尽管大多数编译器允许它们作为扩展。
第一个代码片段不能编译,因为数组下标需要是常量,而它不是。此外,可变长度数组不能在全局范围内声明。
第二个代码片段不能编译,因为可变长度数组在c99之前不是标准的一部分。
第三段代码可以编译,因为c++中const声明产生的常量表达式与C不同。
在C语言中,只有具有自动存储时间的数组对象可以是可变长度数组。在文件范围内声明的对象不能具有自动存储持续时间。
在第二个代码示例中,c89/c90没有可变长度数组,您必须使用c99编译器才能使用该特性。如果您使用的是gcc
,则可以选择带有-std=c99
选项的c99。或者您可以使用最新版本的c: c11。
c++没有可变长度数组
从C99开始才支持可变长度数组,并且它们不能是全局的:
C11、数组声明符,6.7.6.2:
如果一个标识符被声明为具有可变修改的类型,则该标识符将被调用应为普通标识符(定义见6.2.3),没有链接,并且具有块作用域或函数原型作用域。如果标识符被声明为静态或线程对象
存储期限,它不能是可变长度数组类型。
是,而?
对于数组的大小,不同的C和c++语言有不同的规则。在第一种情况下,您正在编译到经典的ANSI (C89/90)。
c++允许使用(常量)作为数组大小,C99也是如此。请注意,"原始的"c++ ANSI标准比1990年更新,因此它在C99标准中添加了许多东西。
- C++模板选择 - 不寻常的情况
- C 结构具有CHAR数组以不寻常的方式初始化为零
- 以不寻常的方式创建指针
- Box2D不寻常的错误.为什么 0阻止错误
- 布尔表达的不寻常使用
- 未定义的参考C ,不寻常的情况
- C++可变参数模板不寻常的例子
- Python 和 C++ 程序之间的不寻常速度差异
- C++中不寻常的iostream事件
- C++如何替换代码中不寻常的引号
- 连接(以一种不寻常的方式)信号到插槽
- TaskDialogIndirect返回一个不寻常的错误代码
- 将 istream 中的字符回显到不寻常的"device"
- 如何根据不寻常数字的数量对数组进行排序
- 微控制器显示驱动程序需要在C或c++中进行不寻常的字符串连接
- 这段c++代码是如何处理不寻常的单个布尔语句的?
- c++中不寻常的FOR语句形式
- 为什么printf()在递归函数中显示不寻常的行为
- c++中不寻常的类型定义
- 一个相当不寻常的野牛错误