本文介绍了在gcc中将2D数组初始化为0时,值不正确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

#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时,值不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 20:27