2015-09-25 56 views
9

所以我有以下簡單片段:在由generate()產生的SquareMatrix<int, 2>data陣列的爲什麼這個constexpr函數在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; 
} 

預期內容是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 ++錯誤還是我失去了一些東西?

回答

7

這看起來涉及到gcc的錯誤[5 regression] Constant expression factory function initializes std::array with static storage duration strangely,如果我們嘗試這與gcc head live example它工作正常。

的錯誤報告具有以下類似的例子,其中,所述靜態變量情況下表現出類似的問題而自動變量的情況下不會:

#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 
} 
相關問題