5

The following code is not possible to compile. I'm wondering why:

#include <string>

constinit std::string constinit_string; // WORKS
constinit thread_local int my_int; // WORKS

constinit thread_local std::string const_init_thread_local; // DOESN'T WORK
// ERROR BY GCC 
//error: 'constinit' variable 'const_init_thread_local' does not have a constant initializer

// ERROR BY CLANG
//error: variable does not have a constant initializer

Link to Godbolt.

Also, MSVC doesn't allow constinit thread_local std::vector, though Clang and GCC do.

I know that in MSVC neither std::string nor std::vector are allowed to be "constinit" at all in Debug mode because I believe they make debug-related allocations, still in Release mode MSVC doesn't allow constinit thread_local for both std::string and std::vector. And Clang and GCC both disallow constinit thread_local for std::string.

6
  • Because you declare the variable constinit_string twice, with different storage classifiers? At least that's what the error message is saying. Have you tried to change the name of one of the variables? Commented Feb 26 at 8:27
  • @Someprogrammerdude I think the OP means the 2nd constinit_string (with the thread_local) does not compile even if you comment out the first (as you can try in the Godbolt link). Commented Feb 26 at 8:30
  • @wohlstad That may be so, but the error in both the question and in the compiler explorer link is unrelated to that fact. Commented Feb 26 at 8:33
  • @Someprogrammerdude You're right, I edited the question and made another link to Godbolt. Commented Feb 26 at 8:47
  • The reason could be that std::string doesn't zero-fill itself fully, making the default constructor non-constant (similar to this situation). The compiler is being lenient in case of global initialization since that automatically zero-fills everything, but is being stricter in case of thread_local initialization. Commented Feb 26 at 10:57

1 Answer 1

-1

Threads have their own stack, but implementing a thread-local heap is difficult. The compiler does not know how much to allocate on the stack for the string. You could put it on the top of the stack and increase the stack pointer when initialising, but what if you have two strings? Furthermore, std::string is a datatype defined in the standard library, not the compiler, so its ability to reason about it is limited. I think it is sensible for a compiler to reject this code.

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

Comments

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.