web-dev-qa-db-fra.com

constexpr const vs variables constexpr?

Il semble évident que constexpr implique const et donc il est courant de voir:

constexpr int foo = 42; // no const here

Cependant si vous écrivez:

constexpr char *const str = "foo";

Ensuite, GCC générera "avertissement: conversion obsolète de la constante de chaîne en" char * "" si l'indicateur -Wwrite-string est passé.

L'écriture:

constexpr const char *const str = "foo";

résout le problème.

Donc constexpr const et constexpr sont-ils vraiment les mêmes?

37
Thomas Moulard

Le problème est que dans une déclaration de variable, constexpr applique toujours le const- ness à l'objet déclaré; const d'autre part peut s'appliquer à un type différent, selon l'emplacement.

Donc

constexpr const int i = 3;
constexpr int i = 3;

sont équivalents;

constexpr char* p = nullptr;
constexpr char* const p = nullptr;

sont équivalents; les deux font p un pointeur const vers char.

constexpr const char* p = nullptr;
constexpr const char* const p = nullptr;

sont équivalents. constexpr crée p un const pointeur. Le const dans const char * fait p pointer vers const char.

61
T.C.

Le message d'erreur que vous voyez n'a rien à voir avec le mot clé constexpr en soi.

Une chaîne littérale comme "foo", comme dans:

somefunction("foo");

Le type de ce littéral de chaîne est const char *. La déclaration suivante:

char *const str = "foo";

Cela tente d'attribuer un const char * valeur à char * valeur. La résultante char * la valeur n'est pas modifiable, constante, mais à ce moment-là, l'erreur s'est déjà produite: une tentative de conversion d'un const char * à un char *.

Le mot clé constexpr dans votre exemple n'est qu'une distraction et n'a aucune incidence sur l'erreur.

3
Sam Varshavchik