Considérez ce code simple:
void g();
void foo()
{
volatile bool x = false;
if (x)
g();
}
Vous pouvez voir que gcc
ni clang
optimiser l'appel potentiel à g
. Ceci est correct dans ma compréhension: la machine abstraite est de supposer que les volatile
variables peuvent changer à tout moment (en raison, par exemple, d'une cartographie matérielle), donc le pliage constant de l' false
initialisation dans la if
vérification serait faux.
Mais MSVC élimine g
complètement l'appel à (en conservant les lectures et les écritures volatile
!). Ce comportement est-il conforme aux normes?
Contexte: J'utilise parfois ce type de construction pour pouvoir activer / désactiver la sortie de débogage à la volée: le compilateur doit toujours lire la valeur de la mémoire, donc changer cette variable / mémoire pendant le débogage devrait modifier le flux de contrôle en conséquence . La sortie MSVC relit la valeur mais l'ignore (probablement en raison du pliage constant et / ou de l'élimination du code mort), ce qui, bien sûr, annule mes intentions ici.
Modifications:
L'élimination des lectures et écritures
volatile
est discutée ici: Est-il permis à un compilateur d'optimiser une variable volatile locale? (merci Nathan!). Je pense que la norme est très claire: ces lectures et écritures doivent avoir lieu. Mais cette discussion ne couvre pas s'il est légal pour le compilateur de prendre les résultats de ces lectures pour acquis et d'optimiser en fonction de cela. Je suppose que cela est sous / non spécifié dans la norme, mais je serais heureux si quelqu'un me prouvait le contraire.Je peux bien sûr créer
x
une variable non locale pour contourner le problème. Cette question est plus par curiosité.