在gcc中将2D数组初始化为0时,值不正确 [英] Incorrect values when initializing a 2D array to 0 in gcc

查看:96
本文介绍了在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.

推荐答案

如果我们查看

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++:

G ++支持C ++ 1y可变长度数组. G ++长期以来一直支持GNU/C99风格的VLA,但现在还支持初始化程序和通过引用捕获lambda.在C ++ 1y模式下,G ++将抱怨标准草案不允许的VLA使用,例如形成指向VLA类型的指针或将sizeof应用于VLA变量.请注意,现在看来VLA不会成为C ++ 14的一部分,而是成为单独的文档的一部分,然后可能是C ++ 17的一部分.

G++ supports C++1y variable length arrays. G++ has supported GNU/C99-style VLAs for a long time, but now additionally supports initializers and lambda capture by reference. In C++1y mode G++ will complain about VLA uses that are not permitted by the draft standard, such as forming a pointer to VLA type or applying sizeof to a VLA variable. Note that it now appears that VLAs will not be part of C++14, but will be part of a separate document and then perhaps C++17.

我们可以看到在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:

(在第16条评论中回复Jakub Jelinek)

(In reply to Jakub Jelinek from comment #16)

此处的错误是G ++接受的VLA初始化程序中的元素数量超过了VLA中的可用空间,然后在运行时将多余的元素丢弃到堆栈中.这是相对于GCC 4.9.3的回归,它实现了n3639( 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时,值不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆