c++constexpr

Difference between MSVC and GCC/Clang for constexpr constructor


EDIT: this was a compiler issue and has now been resolved by Microsoft. Refer to https://developercommunity.visualstudio.com/t/C-compiler-regression-constexpr-constr/10677725.

I would please like some help understanding why the following code does not compile in MSVC (/std:c++20) but does in GCC and Clang. Seems to be related to the constexpr constructor maybe.

#include <iostream>
#include <array>
    
    
class TestX
{
    bool GetA(char * outVal, unsigned int outValLen) {(void)outVal, (void)outValLen; return false;}

    struct SupportedParam
    {
        using GetParamFunc = bool (TestX::*)(char * outVal, unsigned int outValLen);
        constexpr SupportedParam(GetParamFunc gp) : GetParam(gp) {}
        GetParamFunc GetParam;
    };
    
    static const auto & SupportedParameters()
    {
        static constexpr std::array<SupportedParam,1> t =  
        {
            SupportedParam(&TestX::GetA)
        };
        static_assert(t[0].GetParam == &TestX::GetA);
        return t; 
    };
    
public:
    
    void Print()
    {
        for(auto & x : SupportedParameters())
        {
            std::cout << (this->*x.GetParam)(nullptr, 0);
        }
    }
};
    
    
int main(void)
{
    TestX x;
    x.Print();
}

Solution

  • This seems to be a regression/bug in the latest msvc version starting from 19.36.

    As a workaround you could define SupportedParameters outside TestX as shown below:

    class TestX
    {
    //other code as before
    
    //this is a declaration
    static const std::array<SupportedParam,1>&  SupportedParameters();
    public:
    
    //other code as before 
    }; 
    //out of class definition workaround
    const std::array<TestX::SupportedParam,1>&  TestX::SupportedParameters()
    {
         static constexpr std::array<SupportedParam,1> t =  
        {
            SupportedParam(&TestX::GetA)
        };
        static_assert(t[0].GetParam == &TestX::GetA);
        return t;
    } 
    

    Working demo