为什么这个 constexpr 函数在 gcc 的不同情况下给出不同的结果?
Why is this constexpr function giving different results under different circumstances in gcc?
所以我有以下简单的片段:
template <typename T, size_t size>
struct SquareMatrix {
public:
T data[size * size];
constexpr T & operator()(const size_t row, const size_t col) noexcept {
return data[row * size + col];
}
};
constexpr auto generate() {
auto result = SquareMatrix<int, 2>{};
result(0, 0) = 1;
result(1, 0) = 3;
result(0, 1) = 2;
result(1, 1) = 4;
return result;
}
generate()
生成的 SquareMatrix<int, 2>
中 data
数组的预期内容是 1, 2, 3, 4
。然而...
constexpr auto test = generate();
int main() {
for (size_t i = 0; i < 4; ++i) {
std::cout << test.data[i] << std::endl;
}
return 0;
}
如果我使用 g++ 5.2 和 -std=c++14
编译并 运行 这段代码,打印到控制台的结果奇怪地是 1032
.
如果删除 constexpr 限定符以便它在 运行 时执行,或者如果我改写以下任一细微变化:
int main() {
constexpr auto test = generate();
for (size_t i = 0; i < 4; ++i) {
std::cout << test.data[i];
}
return 0;
}
...或...
constexpr auto generate() {
auto result = SquareMatrix<int, 2>{};
result(0, 0) = 1;
result(0, 1) = 2; // this line and
result(1, 0) = 3; // this line have been swapped
result(1, 1) = 4;
return result;
}
constexpr auto test = generate();
int main() {
for (size_t i = 0; i < 4; ++i) {
std::cout << test.data[i];
}
return 0;
}
...预期结果 1234
已打印。此外,clang++ 3.7.0 在所有情况下都会打印预期的 1234
。
我是遇到了 g++ 错误还是遗漏了什么?
这看起来与 gcc 错误有关 [5 regression] Constant expression factory function initializes std::array with static storage duration strangely and if we try this with gcc head live example 它工作正常。
错误报告有以下类似的例子,其中静态变量 case 表现出类似的问题而自动变量 case 没有:
#include <array>
#include <cassert>
namespace /* anonymous */
{
constexpr auto
make_array(const int val) noexcept
{
std::array<int, 2> result = { { val, 0 } };
return result;
}
// Replacing `constexpr` by `const` doesn't change anything.
constexpr auto numbers_static = make_array(42);
}
int main()
{
const auto numbers_automatic = make_array(42);
assert(numbers_automatic[0] == 42); // okay
assert(numbers_static[0] == 42); // fails
}
所以我有以下简单的片段:
template <typename T, size_t size>
struct SquareMatrix {
public:
T data[size * size];
constexpr T & operator()(const size_t row, const size_t col) noexcept {
return data[row * size + col];
}
};
constexpr auto generate() {
auto result = SquareMatrix<int, 2>{};
result(0, 0) = 1;
result(1, 0) = 3;
result(0, 1) = 2;
result(1, 1) = 4;
return result;
}
generate()
生成的 SquareMatrix<int, 2>
中 data
数组的预期内容是 1, 2, 3, 4
。然而...
constexpr auto test = generate();
int main() {
for (size_t i = 0; i < 4; ++i) {
std::cout << test.data[i] << std::endl;
}
return 0;
}
如果我使用 g++ 5.2 和 -std=c++14
编译并 运行 这段代码,打印到控制台的结果奇怪地是 1032
.
如果删除 constexpr 限定符以便它在 运行 时执行,或者如果我改写以下任一细微变化:
int main() {
constexpr auto test = generate();
for (size_t i = 0; i < 4; ++i) {
std::cout << test.data[i];
}
return 0;
}
...或...
constexpr auto generate() {
auto result = SquareMatrix<int, 2>{};
result(0, 0) = 1;
result(0, 1) = 2; // this line and
result(1, 0) = 3; // this line have been swapped
result(1, 1) = 4;
return result;
}
constexpr auto test = generate();
int main() {
for (size_t i = 0; i < 4; ++i) {
std::cout << test.data[i];
}
return 0;
}
...预期结果 1234
已打印。此外,clang++ 3.7.0 在所有情况下都会打印预期的 1234
。
我是遇到了 g++ 错误还是遗漏了什么?
这看起来与 gcc 错误有关 [5 regression] Constant expression factory function initializes std::array with static storage duration strangely and if we try this with gcc head live example 它工作正常。
错误报告有以下类似的例子,其中静态变量 case 表现出类似的问题而自动变量 case 没有:
#include <array>
#include <cassert>
namespace /* anonymous */
{
constexpr auto
make_array(const int val) noexcept
{
std::array<int, 2> result = { { val, 0 } };
return result;
}
// Replacing `constexpr` by `const` doesn't change anything.
constexpr auto numbers_static = make_array(42);
}
int main()
{
const auto numbers_automatic = make_array(42);
assert(numbers_automatic[0] == 42); // okay
assert(numbers_static[0] == 42); // fails
}