g++(4.7.2)错误或功能,在编译时初始化静态数组时?

Posted

技术标签:

【中文标题】g++(4.7.2)错误或功能,在编译时初始化静态数组时?【英文标题】:g++ (4.7.2) bug or feature, when initializing static arrays at compile-time? 【发布时间】:2014-01-29 15:28:46 【问题描述】:

好的,所以我试图通过在编译时初始化一堆 constexpr static int const 数组来做一些聪明的事情。尽管运行时性能根本不受初始化这些数组的控制,但这似乎是一个有趣的小练习。我写了一个测试设置来看看它是否可能,我最终能够做到这一点:

struct Test

    constexpr static int const array[10] = Array<int, 10, 0, Increment>::array;
;

constexpr int const Test::array[10];

int main()

    cout << Test::array[3] << '\n';

这里,Array 有一个名为 array 的静态成员,它包含 10 个 ints,从 0 开始,其中每个后续元素的值由名为 Increment 的模板元编程函子确定(即 @ 987654328@)。正如预期的那样,程序打印出数字3

太棒了,对吧?我现在可以编写仿函数并在编译时初始化数组将各种时髦的模式。下一步:通过使Test 像这样的类模板来取消对数组大小 10 的硬编码:

template <size_t Size>
struct Test

    constexpr static int const array[Size] = Array<int, Size, 0, Increment>::array;
;

template <size_t Size>
constexpr int const Test<Size>::array[Size];

int main()

    cout << Test<10>::array[3] << '\n';

但是,突然之间,它不再与消息一起编译:

test.cc:43:72: error: array must be initialized with a brace-enclosed initializer

为什么会这样?一旦我将类转换为类模板,这种初始化是否会变得无效,或者我是否偶然发现了 GCC 中未实现/错误的东西?

仅供参考,我可以根据要求发布我的其余代码(例如 Array 的实现)。现在我认为这应该足够了。

编辑 可以使用 Array 的不同的、简单的实现来重现该错误,以节省一些空间:

template <size_t Size>
struct Array

    constexpr static int const array[Size] = ;
;

template <size_t Size>
struct Test

    constexpr static int const array[Size] = Array<Size>::array;
;

【问题讨论】:

尝试更新的 gcc(ideone.com 在线有 4.8)。我无法用 4.8 重现错误。 @n.m.它在 C++11 上给出了同样的错误,我不确定如何将 --std=c++11 传递给他们的 4.8.1 编译器...... @JorenHeit 他们有 C++11 模式和常规 C++ 模式。你也可以试试 Coliru。 @n.m.在他们提供 gcc-4.8.1 的地方尝试了 gcc.godbolt.org 并遇到了同样的问题。 @JorenHeit 虽然问题可能与您的问题不完全相同,但请仔细阅读答案!点赞最多的人很好地解释了为什么在初始化 std::array 时必须使用一对额外的大括号。 【参考方案1】:

关注是违法的;

static const int a[10] = ;
static const int b[10] = a; // Illegal

所以gcc的bug其实是针对非模板情况的。

您可以使用 std::array 代替 C 数组。

【讨论】:

即使ab 都被声明为constexpr? 谢谢!我将我所有的 C 数组都切换为 std::arrays,当然,还使用了双括号来初始化它,现在它可以工作了 :-) 非常感谢。

以上是关于g++(4.7.2)错误或功能,在编译时初始化静态数组时?的主要内容,如果未能解决你的问题,请参考以下文章

使用地址清理程序和附加 asan 标志进行静态初始化顺序时出现 g++ 5 和 6 的错误

使用 PostgreSQL 编译静态 Qt 5.10.0 时出错

C++,我可以在编译时静态初始化 std::map 吗?

gdb 7.5.1 调试通过 g 4.7.2 构建的可执行文件的问题

在 OS X 上设置 g++

编译错误:“g++:尝试执行 'cc1plus' 时出错:execvp:没有这样的文件或目录”