【问题标题】:C++ variable-sized object may not be initializedC++ 可变大小对象可能未初始化
【发布时间】:2019-02-21 03:28:21
【问题描述】:

我有以下简单的来源

#include <iostream>

int main() {
    int nv;
    nv = 3;
    int arr[nv] = { 0, 2, 5 };
    return 0;
}

在系统 1 上使用 GCC 编译时,我得到了

error: variable-sized object ‘arr’ may not be initialized.

在系统 2 上使用 GCC 编译时,我没有收到任何错误。

两种情况下的编译标志相同,见下文。

这是什么原因,我怎样才能让我的代码在系统 1 中编译? 我怀疑它与 gcc 版本有关,但我没有找到支持这种怀疑的信息。

在系统 1 中:

$ g++ --version
g++ (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
...
$ make
g++ -MMD -g -g3 -Wall -Wunused -Wuninitialized -Wextra -fmessage-length=0 -std=gnu++11 -c -o obj/arrays_test.o src/arrays_test.cc
...

在系统 2 中:

$ g++ --version
g++ (Ubuntu 5.5.0-12ubuntu1~16.04) 5.5.0 20171010
...
$ make
g++ -MMD -g -g3 -Wall -Wunused -Wuninitialized -Wextra -fmessage-length=0 -std=gnu++11 -c -o obj/arrays_test.o src/arrays_test.cc
...

【问题讨论】:

  • 我添加了 g+ 标签来帮助集中问题。比起标准 C++,更多的是 GCC 的变化。
  • 只是想知道:这真的是一个最小的例子吗? IE。 if (true) 是必要的吗?我可以推测这个问题 - 编译器是否知道 nv==3 在运行时int arr[nv] = { 0, 2, 5 }; 行何时执行?
  • 不使用指定不当的 gcc 扩展是确保代码可移植性的良好第一步。还要避免过时的 gcc 版本。
  • @VTT OP 明确使用带有-std=gnu++11 的 gcc 扩展。 argumentum ad standard 不适用。
  • 缩小范围:GCC 4.9.2 (Debian 4.9.2-10) 的行为类似于 GCC 5.5(无错误)

标签: c++ arrays initialization g++ variable-length-array


【解决方案1】:

这里的问题是您使用的不是一个而是两个扩展。

如前所述,第一个扩展是您在 C++ 中使用 C99 VLA。那是documented GCC extension

第二个扩展是即使 C99 也不允许 VLA 的初始化程序:

C99 §6.7.8 [初始化]

要初始化的实体的类型应该是一个未知数组 大小或非可变长度数组类型的对象类型。

(在 C11 中,您会在 §6.7.9 中找到此限制)。但正如链接的 GCC 页面所示,这不是官方的 Gnu 扩展。 C99 的限制仍然存在。您需要使用赋值而不是初始化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-28
    • 1970-01-01
    相关资源
    最近更新 更多