Quel est le bon compilateur ?
Clang a raison.
La définition d'un constexpr
conformément à l'article dcl.constexpr/3
La définition d'un constexpr
doit satisfaire aux conditions suivantes suivantes :
(3.1) son type de retour doit être un type littéral ;
(3.2) chacun de ses types de paramètres est un type littéral ;
(3.3) son organe fonctionnel est le suivant = delete
, = default
, qui fait pas contenir :
(3.3.1) une définition asm,
(3.3.2) une instruction goto,
(3.3.3) une étiquette d'identification,
(3.3.4) un bloc d'essai, ou
(3.3.5) a définition d'une variable de type non littéral ou de statique ou la durée de stockage du fil ou pour laquelle aucune initialisation n'est effectuée.
Également selon dcl.constexpr/5 :
Pour un constexpr
ou un constructeur constexpr qui n'est ni par défaut ni un modèle, si aucune valeur d'argument n'existe s l'invocation de la fonction ou du constructeur pourrait être a d'une expression constante de base,
Foo(true)
pourrait être évaluée à un expression de la constante de base (c'est-à-dire 1
).
En outre, Foo(false)
pourrait être mais il n'est pas nécessaire qu'elle soit évaluée en permanence.
CONCLUSION
Ainsi, un insecte dans le CCG.
Merci à @Barry, @aschepler et @BenVoigt pour m'avoir aidé à répondre à cette question.
1 votes
@AnT - J'ai besoin d'une feuille de contrôle pour garder les contraintes C++11, C++14 et C++17 en ordre.
0 votes
Aucune ne fonctionne si vous forcez l'évaluation au moment de la compilation.
constexpr int a = Foo(false)
mais je ne sais pas si l'un ou l'autre est incorrect.2 votes
Il me semble qu'il s'agit d'un bogue de base dans gcc.
3 votes
Certainement un bogue de gcc, soumis 86327
2 votes
Il est intéressant de noter que clang ne permet pas à la fonction d'être évaluée comme une expression constante sur la branche qui effectue la modification de
global
(comme l'a noté @user975989), et si vous supprimez l'optionif (arg) return 1;
il ne compilera pas du tout, bien qu'il réponde aux exigences listées dans la réponse de @codekaiser.0 votes
@JohnIlacqua : Au moins la première partie n'est pas du tout surprenante car autoriser cela violerait le point "modification d'un objet" dans [expr.const].