0

This code builds successfully with Clang 20.1.10 and with GCC 15.1, but not with Microsoft Visual C++ 2022 version 17.14.0:

#include <array>
#include <string>

int main()
{
    static constexpr std::array<std::string, 3> as{ "a", "bb", "ccc" };

    static_assert(as[2] == "ccc");
}

The error is:

Code: C2131
Description: expression did not evaluate to a constant

Can I make this code work with Visual C++?

Who is on the right side? GCC and Clang or Visual C++?

8
  • 1
    Compiles well Commented Jun 10 at 16:21
  • 2
    Please specify the compiler flags you used. AFAIK std::string is not constexpr until C++20. Commented Jun 10 at 16:42
  • Fails compilation in clang when C++17 is used. Also fails for gcc in C++17 mode. Commented Jun 10 at 16:43
  • 3
    Maybe you didn't enable c++20 on msvc. Remember that the default is c++14. Commented Jun 10 at 17:04
  • 2
    Compiler regression? MSVC++ builds this code as C++20, but not as C++23! godbolt.org/z/jrYr1717Y Commented Jun 10 at 19:14

2 Answers 2

3

std::string can be used in constexpr expression (C++20), but you cannot really have constexpr std::string as allocation should stay in the constant expression.

So to have constexpr std::string, you have to be in the limit of SSO (Small String Optimization). SSO is not mandatory either, so all compilers are right.

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

Comments

1

Posting as an answer instead of a comment since it's presumably (likely/hopefully) the following issue:

Visual C++ does not accept constexpr string while gcc can

MSFT Bot claims it was fixed at the above link and a quick test shows it is (in MSVC 19.34, VS 17.4, though you'ld have to check the exact build and revision numbers, assuming they're not zero), but I can't find any official reference to the fix in their actual release notes for those versions (after a quick search only). FYI you may also want to check out the the C++ constants __cpp_lib_constexpr_string and __cpp_lib_constexpr_dynamic_alloc. In MSVC they seem to have been #defined starting in MSVC 19.29, VS 16.11 (though again, would have to check the exact build and revision numbers but your particular version is well ahead of it anyway).

Jardod42 also makes a very good point about SSO for larger strings (yours are easily short enough) though IMHO it completely violates the point of having a C++ standard (not really a standard if you can't write standardized/portable code that might fail to compile because of an implementation issue like SSO, but I digress).

Lastly, you may want to consider using std::string_view instead if suitable for your needs.

1 Comment

Yes, I confirm that std::string_view is accepted by Visual C++ 17.14.0. std::string is accepted by Visual C++ 19.34.0.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.