2

I had code similar to this:

#define STR "ABC"
// ...
char s[] = STR;
puts(s);
s[2] = '!';
puts(s);

And I tried to modernize it with constexpr:

constexpr char STR[] = "ABC"
// ...
char s[] = STR;
puts(s);
s[2] = '!';
puts(s);

But it no longer compiles.

How can I initialize a string on the stack from a constexpr constant without runtime penalty?

Paul
  • 6,061
  • 6
  • 39
  • 70
  • Can you please elaborate on your "runtime penalty" requirement? Why do you have it? What problem does a "runtime penalty" give you? Have you tried to measure and benchmark and profile to learn that it's really a top-two (or possibly top-three) bottleneck in your system? – Some programmer dude Nov 25 '22 at 10:01
  • There's no problem and no bottleneck, I'm just trying to educate myself, and I'm asking how it's possible to do that in C++. I can as well use Python, but the question is about C++. – Paul Nov 25 '22 at 10:03

1 Answers1

5

C-style arrays can only be initialized by literals, not by another array or const char*.

You can switch to std::array

constexpr std::array<char,4> STR{"ABC"};
int main() {
std::array s{STR};
// OR: auto s{STR};
}

Unfortunately, it requires specifying the length of the string literal in STR, if you have C++20, you can use std::to_array:

constexpr std::array STR{std::to_array("ABC")};

optionally replacing std::array with auto.

If you do not have C++20, you can still use the implementation from the link above to write your own to_array.

There is also std::string_view and std::span but both are non-owning pointers.

Quimby
  • 17,735
  • 4
  • 35
  • 55
  • 1
    That's cool. Actually, I was just able to do: `constexpr char STR[] = "ABC"` and then `auto s{std::to_array(ABC)};`. – Paul Nov 25 '22 at 10:41