3

I have here the case that a function could potentially be constexpr. Normally one adds the constexpr and use the constant evaluation only if the context allows it. However the following code complaints despite not using it in a constexpr context:

template <typename T>
struct Wrapper
{
    friend constexpr bool operator==(const Wrapper& crLhs, const Wrapper& crRhs) noexcept
    {
        return crLhs.m_t == crRhs.m_t;
    }

    T m_t = {};
};

Using Visual Studio 2017 15.9.20 this gives 'error C3615: constexpr function 'operator ==' cannot result in a constant expression' when e.g. instantiated for std::string. The information is correct but I am not instantiating it in a constexpr context.

void f()
{
   bool b;

   Wrapper<int>  a;

   b = a == a; //ok

   Wrapper<std::string> c;

   b = c == c;  //C3615, but not using constexpr context
}

I can apply a workaround it by using a member template or drop the constexpr but is there fancy trick here to have the best of both worlds (i.e. constexpr when applicable)?

4
  • constexpr does not mean that it is evaluated at compile time (as you already know), but it does mean it must be possible to evaluate it at compile time Commented Feb 25, 2020 at 16:46
  • @idclev: I know and it can potentially be evaluated at compile time for certain types. Hence the constexpr. Only not for other types. constepxr is cool that you can also invoke it in a none constexpr context. But not if this errors pops up in above case. Commented Feb 25, 2020 at 16:47
  • if you know it then why does it matter that you do not use/instantiate it in a constexpr context? Anyhow, it doesnt change the actual question. Commented Feb 25, 2020 at 16:50
  • @idclev: this is a simplified case. It's a kind of wrapper; sometimes used for built in types; sometimes for more complex types. For the built in types we use the constexpr evaluation of the equality operator. Commented Feb 25, 2020 at 16:53

1 Answer 1

3

Your code is fine. This is a bug in older versions of MSVC.

This bug was fixed in MSVC version 19.22, and compiles without error. Here we can see a side-by-side of the two compiler versions: https://godbolt.org/z/79kXFm

All versions after and including 19.22 compiles it, but Version 19.21 and below incorrectly give you error C3615, even though both of them are set to use C++11.

GCC and Clang never had this bug.

The bug was only ever in MSVC, and even very old versions of GCC and Clang compile the code without giving you an error.

What should you do?

If possible, you should just move to a newer version of Visual Studio. This is the simplest option to upgrade the compiler, and if you move to a newer version the compiler should receive bug fixes and upgrades. If that's not an option, I would google different ways to upgrade just the compiler itself. This might be helpful.

Sign up to request clarification or add additional context in comments.

7 Comments

FYI /std:c++11 doesn't work (compiler complains). It works starting from argument /std:c++14.
How should I tell it to use C++11 when compiling?
VS introduce this switch after C++11 support was added. In earlier versions you always get newest C++ VS could provide.
Ok thanks. Transferring to new Visual Studio is not that easy due to the many library dependencies.
Do those depend on the older compiler version?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.