Considera questo semplice codice:
void g();
void foo()
{
volatile bool x = false;
if (x)
g();
}
Puoi vedere che gcc
né clang
ottimizzare né ottimizzare la potenziale chiamata a g
. Questo è corretto nella mia comprensione: la macchina astratta è quella di supporre che le volatile
variabili possano cambiare in qualsiasi momento (a causa di essere mappate dall'hardware), quindi piegare costantemente l' false
inizializzazione nel if
controllo sarebbe sbagliato.
Ma MSVC elimina completamente la chiamata g
(mantenendo le letture e le scritture al volatile
pensiero!). Questo comportamento è conforme allo standard?
Background: Occasionalmente utilizzo questo tipo di costrutto per essere in grado di attivare / disattivare l'output di debug al volo: il compilatore deve sempre leggere il valore dalla memoria, quindi cambiando quella variabile / memoria durante il debug si dovrebbe modificare il flusso di controllo di conseguenza . L'output di MSVC rilegge il valore ma lo ignora (presumibilmente a causa della costante piegatura e / o eliminazione del codice morto), che ovviamente sconfigge qui le mie intenzioni.
modifiche:
L'eliminazione delle letture e delle scritture
volatile
viene discussa qui: è consentito a un compilatore di ottimizzare una variabile volatile locale? (grazie Nathan!). Penso che lo standard sia abbondantemente chiaro che quelle letture e scritture debbano avvenire. Ma questa discussione non copre se sia legale per il compilatore dare per scontati i risultati di tali letture e ottimizzarli sulla base di ciò. Suppongo che questo sia sotto / non specificato nello standard, ma sarei felice se qualcuno mi dimostrasse che mi sbagliavo.Ovviamente posso creare
x
una variabile non locale per risolvere il problema. Questa domanda è più per curiosità.