这是否总是按预期运行?可变尺寸阵列的范围
char *x;
if (...) {
int len = dynamic_function();
char x2[len];
sprintf(x2, "hello %s", ...);
x = x2;
}
printf("%s\n", x);
// prints hello
编译器如何(在我的情况GCC)实现可变大小的数组,每个C和C++的?
这是否总是按预期运行?可变尺寸阵列的范围
char *x;
if (...) {
int len = dynamic_function();
char x2[len];
sprintf(x2, "hello %s", ...);
x = x2;
}
printf("%s\n", x);
// prints hello
编译器如何(在我的情况GCC)实现可变大小的数组,每个C和C++的?
编号x2
位于if
语句的作用域的本地,您可以使用指针在其外部访问它。这导致未定义的行为。
顺便说一下,在C11中,VLA已经成为可选项,并且从未成为C++的一部分。所以最好避免它。
另一方面,VLA的(非常)受限形式正在悄悄进入下一个C++标准;-) –
VLA仅在C99中添加,甚至在C99变得普遍之前,它有点尴尬,他们删除了它从标准! –
否,对于两个单独的原因:
C++:该代码是无效的C++。 C++中的数组必须具有编译时常量大小。
C:不,因为该数组只能存在,直到它声明的块的末尾,因此解引用x
是未定义的行为。
从C11,6.2.4/2:
如果对象被称为它的寿命之外,则该行为是未定义的。
而且6.2.4/7说,可变长度数组从声明住直到其封闭范围的末尾:
对于这样一个对象,该对象不具有可变长度数组类型,其生命周期从 延伸到对象的声明,直到程序执行离开 声明的范围。
取决于语言。这是C++中的一个编译器扩展。 – chris
它没有。由于您声明了一个变量char x2 [],因此它会从堆/进程虚拟内存中询问空间并始终保持相同。 当你写x = x2时,你将x指向与x2相同的内存空间,因为x是一个指针,但它不会总是一样,printf x没有初始化就会打印垃圾。 –
根据我的理解,x2在if语句后不复存在,因此无法知道打印输出是什么 – Smash