Intent

Adding an immutable, compile time, static storage duration string to the codebase.

Approach

Simply adding the constant to the Constants.hpp file.

1
2
3
4
//file: .../Constants.hpp
constexpr std::string s_other_constant1 = "some_const1";    
constexpr std::string s_other_constant2 = "some_const2";    
constexpr std::string s_my_constant = "17characterstring";  //our new constant

Observation

Compilation error with the following text:

1
2
3
 error: 'std::__cxx11::basic_string<char>(((const char*)"17characterstring"), std::allocator<char>())' is not a constant expression because it refers to a result of 'operator new'
  200 |             return static_cast<_Tp*>(::operator new(__n));
      |                                      ~~~~~~~~~~~~~~^~~~~

Operator new is the issue?

In our case, we want our constant’s lifetime to be the entire program duration. This means we cannot deallocate in compile time.

But then, why does it work for the other constants?

They must have dynamically allocated memory as well, right?

The “Whimsy”

No, the other constants did not dynamically allocate memory. They used the “Small String Optimization (SSO)” buffer.

Since SSO holds the string content in stack and does not invoke any new calls, it allows creating constexpr std::string objects until a certain length which can remain alive for the entire program duration.

In our case, the compiler allows strings of length 15 at most.

We can easily see this by running the following code:

Interactive · Compiler Explorer

This length is an implementation detail.

Solution

The solution lies in using static memory.

We want strings; therefore, we can use a character array. Good options are:

  1. constexpr std::string_view s_my_const
  2. constexpr char s_my_const[SIZE]

Both expressions create a character array stored in read-only static memory which will stay alive during the entire program duration.

Option 1 is probably more preferable in most cases since it provides many helpful member functions.

Hence, global compile time strings must be short!

(Actually, they should not exist at all…)