问题描述
#include <iostream>
using namespace std;
int main() {
int rows = 10;
int cols = 9;
int opt[rows][cols] = {0};
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
std::cout << opt[i][j] << " ";
}
std::cout << "\n";
}
return 0;
}
输出:
0 32767 1887606704 10943 232234400 32767 1874154647 10943 -1
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
我正在 https://www.codechef.com/ide 中使用gcc 6.3
I'm using gcc 6.3, in https://www.codechef.com/ide
我期望第一行全为零.不是这样吗?
I'm expecting the first row to be all zeros. Shouldn't that be the case?
我用const变量测试了行和列,然后将其初始化为全零.我认为这应该引发编译错误,而不是表现出这种不正确的(并且可能是危险的)行为.
I tested with const variables for rows and cols, and then it initialized to all zeroes. I feel this should throw a compile error instead of exhibiting this incorrect (and potentially dangerous) behavior.
推荐答案
如果我们查看 gcc 4.9发行说明,似乎他们添加了对初始化VLA的支持,并期望在将来的C ++版本中将支持VLA:
If we look at the gcc 4.9 release notes it looks like they added support for initializating VLA with the expectation VLA would be supported in a future version of C++:
我们可以看到在4.9之前,抱怨我们无法初始化VLA
We can see it live that before 4.9 complains we can't initialize a VLA
error: variable-sized object 'opt' may not be initialized
int opt[rows][cols] = {0};
^
但是在 4.9.1之后,它停止抱怨并且没有相同的错误请参阅最新的版本.
but in 4.9.1 and after it stops complaining and it does not have the same bug we see in more recent versions.
所以看起来像是回归.
请注意,clang拒绝允许对其进行扩展的VLA初始化(,)查看实时示例.这很有意义,因为 C99不允许初始化VLA :
Note that clang refuses to allow initialization of a VLA (which they support as an extension) see a live example. Which make sense since C99 does not allow initialization of VLA:
gcc错误69517
gcc 错误报告:具有过多初始化程序元素的VLA上的SEGV 的注释为该功能提供了一些背景知识:
gcc Bug 69517
gcc bug report :SEGV on a VLA with excess initializer elements has a comment that provides some background on this feature:
此处的错误是G ++接受的VLA初始化程序中的元素数量超过了VLA中的可用空间,然后在运行时将多余的元素丢弃到堆栈中.这是相对于GCC 4.9.3的回归,它实现了n3639( http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3639.html ). GCC 4.9更改中对此进行了记录( https://gcc.gnu.org/gcc- 4.9/changes.html ),使用以下示例突出显示该功能:
The bug here is in G++ accepting a VLA initializer with more elements than there is room for in the VLA, and then trashing the stack at runtime with the extra elements. It is a regression with respect to GCC 4.9.3 which implements C++ VLAs as specified in n3639 (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3639.html). This is documented in GCC 4.9 changes (https://gcc.gnu.org/gcc-4.9/changes.html) which highlights the feature using the following example:
void f(int n) {
int a[n] = { 1, 2, 3 }; // throws std::bad_array_length if n < 3
...
随后从C ++中删除了VLA,并从G ++中部分(但不是完全)删除了VLA,这导致在移植到更高版本时,使用G ++ 4.9开发和测试的C ++程序会中断.
VLAs were subsequently removed from C++, and also partially (but not completely) removed from G++, which causes C++ programs developed and tested with G++ 4.9 to break when ported to a later version.
C ++ VLA将更安全地与注释9中引用的修补程序一起使用.该补丁必须从GCC 6.0还原,因为它在Java中引起了问题. Java已被删除,我计划/希望重新提交GCC 8的补丁.(我想为GCC 7提交补丁,但没有得到.)
C++ VLAs will be safer to use with the patch referenced in comment #9. It patch had to be reverted from GCC 6.0 because it caused problems in Java. Java has been removed and I plan/hope to resubmit the patch for GCC 8. (I wanted to do it for GCC 7 but didn't get to it.)
这篇关于在gcc中将2D数组初始化为0时,值不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!