web-dev-qa-db-fra.com

Constexpr si avec une condition non booléenne

Il me semble avoir trouvé quelque chose sur lequel Clang et GCC ne sont pas d'accord. Voici le code:

int main() {
  if constexpr (2) {}
}

Cela se compile avec succès avec GCC 7.4.0, mais il échoue avec Clang 7.0.0 avec ce message d'erreur:

test.cpp:3:17: error: constexpr if condition evaluates to 2, which cannot be narrowed to type 'bool'
      [-Wc++11-narrowing]
  if constexpr (2) {}
                ^
1 error generated.

cppreference ne semble pas mentionner "rétrécissement", donc cela semble être un bug Clang, mais je ne suis pas tout à fait certain. S'il s'agit d'un bogue avec l'un ou l'autre compilateur, a-t-il déjà été signalé?

42
Indiana Kernick

Clang diagnostique sous ces paragraphes

[stmt.if] (c'est moi qui souligne)

2 Si l'instruction if est de la forme if constexpr, la valeur de la condition doit être une expression constante de type bool convertie contextuellement ; ce formulaire est appelé une instruction if constexpr.

[expr.const]

4 Une expression constante convertie de type T est une expression, convertie implicitement en type T, où l'expression convertie est une expression constante et la séquence de conversion implicite ne contient que

  • conversions intégrales autres que les conversions rétrécissantes,

Maintenant, en ce qui concerne les conversions intégrales, une conversion en boolest répertoriée comme une conversion intégrale . Et il se rétrécit, au sens strict du mot, car un booléen ne peut pas représenter toutes les valeurs d'un int. Le diagnostic n'est donc pas sans fondement.

Mais je pense qu'il est également tout à fait raisonnable de considérer le fait qu'une conversion en bool est généralement destinée à vérifier la "véracité", et donc la nature rétrécissante de celle-ci ne devrait pas avoir d'importance. Il ressemble à un bug mineur dans la norme1, GCC empruntant la voie du bon sens, et Clang adhérant à la lettre sèche de la loi au sens le plus strict.


1 - Et ne proposition existe pour le changer .

Nous le disons, mais c'est caché. "Expression constante convertie en contexte de type bool" est un terme technique standard qui exclut le rétrécissement des conversions.

Clang a raison.

12
T.C.