Considere este código simples:
void g();
void foo()
{
volatile bool x = false;
if (x)
g();
}
Você pode ver que gcc
nem clang
otimiza a chamada potencial para g
. Isso está correto no meu entendimento: A máquina abstrata deve assumir que as volatile
variáveis podem mudar a qualquer momento (devido a serem, por exemplo, mapeadas por hardware), portanto, dobrar constantemente a false
inicialização na if
verificação estaria errado.
Mas o MSVC elimina g
totalmente a chamada (mantendo as leituras e gravações no volatile
entanto!). Esse comportamento é compatível com os padrões?
Antecedentes: Ocasionalmente uso esse tipo de construção para ativar / desativar a saída de depuração on-the-fly: O compilador sempre deve ler o valor da memória, portanto, alterar a variável / memória durante a depuração deve modificar o fluxo de controle adequadamente . A saída MSVC relê o valor, mas o ignora (provavelmente devido à constante dobragem e / ou eliminação do código morto), o que obviamente derrota minhas intenções aqui.
Editar% s:
A eliminação das leituras e gravações
volatile
é discutida aqui: É permitido que um compilador otimize uma variável volátil local? (obrigado Nathan!). Eu acho que o padrão é bastante claro de que essas leituras e gravações devem acontecer. Mas essa discussão não cobre se é legal para o compilador considerar os resultados dessas leituras como garantidos e otimizar com base nisso. Suponho que isso seja sub / não especificado no padrão, mas ficaria feliz se alguém me provasse errado.É claro que posso criar
x
uma variável não local para contornar o problema. Esta questão é mais por curiosidade.