J’étais juste choqué que cela soit permis:
if( int* x = new int( 20 ) ) { std::cout << *x << "!\n"; // delete x; } else { std::cout << *x << "!!!\n"; // delete x; } // std:cout << *x; // error - x is not defined in this scope
Donc, est-ce autorisé par la norme ou est-ce juste une extension du compilateur?
PS Comme il y avait plusieurs commentaires à ce sujet – veuillez ignorer que cet exemple est “mauvais” ou dangereux. Je sais ce que. Ce n’est que la première chose qui m’a été donnée à titre d’exemple.
Ceci est autorisé par la spécification, depuis C ++ 98.
De la section 6.4 “Déclarations de sélection”:
Un nom introduit par une déclaration dans une condition (introduite par le spécificateur de type-seq ou le déclarant de la condition) est en vigueur depuis son sharepoint déclaration jusqu’à la fin des sous-éléments contrôlés par la condition.
L’exemple suivant provient de la même section:
if (int x = f()) { int x; // ill-formed, redeclaration of x } else { int x; // ill-formed, redeclaration of x }
Il est standard, même dans l’ancienne version C ++ 98 du langage:
Pas vraiment une réponse (mais les commentaires ne sont pas bien adaptés aux exemples de code), plus une raison pour laquelle il est incroyablement pratique:
if (int* x = f()) { std::cout << *x << "\n"; }
Chaque fois qu'une API retourne un type "option" (qui possède également une conversion booléenne disponible), ce type de construction peut être exploité de sorte que la variable ne soit accessible que dans un contexte où il est judicieux d'utiliser sa valeur. C'est un idiome vraiment puissant.
La définition d’une variable dans la partie conditionnelle d’une instruction while
, if
et switch
est standard. La clause pertinente est 6.4 [stmt.select] paragraphe 1 qui définit la syntaxe de la condition.
BTW, votre utilisation est inutile: si new
échoue, il jette une exception std::bad_alloc
.
Voici un exemple démontrant l’utilisation non typique d’une variable déclarée dans une condition if .
Le type de variable est int &
convertible en booléen et utilisable dans les twigs then et else .
#include #include
la sortie est
john was just born as baby #1 john is already 1 year-old jack was just born as baby #2 john is already 2 year-old jack is already 1 year-old bill was just born as baby #3
Malheureusement, la variable dans la condition ne peut être déclarée qu'avec la syntaxe de déclaration '='.
Cela exclut d'autres cas de types éventuellement utiles avec un constructeur explicite.
Par exemple, l'exemple suivant utilisant un std::ifstream
ne comstackra pas ...
if (std::ifstream is ("c:/tmp/input1.txt")) { // won't comstack! std::cout << "true: " << is.rdbuf(); } else { is.open("c:/tmp/input2.txt"); std::cout << "false: " << is.rdbuf(); }