Pepijn Kramer
Pepijn Kramer

Reputation: 13076

MSVC bug when initializing a constexpr variable via constexpr constructor that accepts a raw array reference?

The following code compiles fine when using the latest GCC & Clang stable versions.

However MSVC gives an error that the initialization of the matrix does not evaluate to a constant. Is this a MSVC bug or do I miss something?

Live example:

<source>(72): error C2131: expression did not evaluate to a constant
<source>(71): note: failure was caused by out of range index 4; allowed range is 0 <= index < 4
#include <cassert>
#include <cstring>
#include <iostream>
#include <utility>
#include <stdexcept>

struct index_t final
{
    constexpr index_t() = default;
    constexpr index_t(const std::size_t r, const std::size_t c) :
        row{ r },
        col{ c }
    {
    }

    std::size_t row{};
    std::size_t col{};
};


template<typename type_t, std::size_t rows_v, std::size_t columns_v>
class matrix_t final
{
public:

    explicit constexpr matrix_t(const type_t(&values)[rows_v][columns_v])
    {
        for (std::size_t row = 0; row < rows_v; ++row)
        {
            for (std::size_t col = 0; col < columns_v; ++col)
            {
                m_values[row][col] = values[row][col];
            }
        }
    }

    constexpr index_t get_index_for_value(const type_t& value) const
    {
        for (std::size_t row = 0; row < rows_v; ++row)
        {
            for (std::size_t col = 0; col < columns_v; ++col)
            {
                if (m_values[row][col] == value)
                {
                    return index_t{ row,col };
                }
            }
        }
        throw std::invalid_argument("value not found in array");
    }

    constexpr auto operator[](const std::size_t row) const
    {
        return &m_values[row][0];
    }


private:
    type_t m_values[rows_v][columns_v]{};
};


// Intialization of matrix : error C2131: expression did not evaluate to a constant
// message : failure was caused by out of range index 4; allowed range is 0 <= index < 4
constexpr matrix_t matrix   
{ {
    { 18, 39, 91, 91 },
    { 67,  3,  9, 95 },
    { 69,  3, 68, 93 },
    { 69, 21, 92, 92 }
} };

int main()
{
    static_assert(matrix[1][1] == 3);
    static_assert(matrix.get_index_for_value(68).row == 2);
    static_assert(matrix.get_index_for_value(68).col == 2);
    return 0;
}

Upvotes: 5

Views: 240

Answers (1)

Pepijn Kramer
Pepijn Kramer

Reputation: 13076

The bug has been confirmed here Incorrect-Index-Out-of-Range-Error

Upvotes: 2

Related Questions