Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why must a string be constructed at run-time? [duplicate]

Tags:

Can C-Strings or std::strings be created as constexpr or must they be created at run-time?

With gcc 4.9.2 I can do this:

constexpr const char foo[] = "blee"; 

(Sadly the November 2013 Customer Technology Preview does not allow Visual Studio to support this: https://stackoverflow.com/a/29255013/2642059)

But even with gcc 4.9.2 I cannot do this:

constexpr const std::string foo = "blee"; 

I get the error:

error: the type 'const string {aka const std::basic_string<char>}' of constexpr variable 'foo'         is not literal   constexpr const std::string foo = "blee";                                    ^ note: 'std::basic_string<char>' is not literal because:      class basic_string            ^ note:   'std::basic_string<char>' has a non-trivial destructor 

But I would like more clarification on why a std::string is not a literal. That is to say: Why must a string be constructed at run-time?

As pointed out this question can partially be answered by this: Is it possible to use std::string in a constexpr? but it does not touch on the why std::string can not be a literal which is core to the question.

like image 200
Jonathan Mee Avatar asked Mar 25 '15 12:03

Jonathan Mee


1 Answers

There is a proposal for a constexpr string: Compile-Time String: std::string_literal and it says:

The purpose of std::string_literal, like std::string, is to provide a convenience utility for working with text. Unlike std::string, an instantiation of std::string_literal is a literal type and so can be used at compile­time. That is, it may be the type of an constexpr object, and it may be the type of a parameter, return value or local variable of a constexpr function

which also confirms that indeed std::string is not a literal type.

So why not just make std::string a literal type?

We get a hint why from the proposal above why this not possible:

This would require a massive core language change to make something like dynamic memory available at compile­-time, or to make something like VLA/ARB and permit them in literal types. Given the violently negative reaction of Rapperswil Evolution to not only N4025 (Classes of Runtime Size), but anything that vaguely resembles VLA/ARBs, we can expect this not to happen any time soon, so this idea is a non­starter.

std::string requires dynamic memory which is not available at compile time.

Why constexpr can not be applied to std::string but can to array of char

constexpr applied to an object shall be applied to a literal type which does not apply to std::string but applies to an array of const char. From the draft C++11 standard section 7.1.5 [dcl.constexpr] (emphasis mine going forward):

A constexpr specifier used in an object declaration declares the object as const. Such an object shall have literal type and shall be initialized. If it is initialized by a constructor call, that call shall be a constant expression (5.19). […]

and from section 3.9 [basic.types]:

A type is a literal type if it is:

and includes:

  • a scalar type; or
  • an array of literal type

Arithmetic types are scalar types and include char, which covers the array of const char

and for classes:

a class type (Clause 9) that has all of the following properties:

  • it has a trivial destructor,
  • every constructor call and full-expression in the brace-or-equal-initializers for non-static data members (if any) is a constant expression (5.19),
  • it is an aggregate type (8.5.1) or has at least one constexpr constructor or constructor template that is not a copy or move constructor, and
  • all of its non-static data members and base classes are of literal types.

std::string does not meet that criteria.

like image 154
Shafik Yaghmour Avatar answered Dec 23 '22 17:12

Shafik Yaghmour