Como uma variável no mesmo endereço produz 2 valores diferentes?

Considere isto :

#include  using namespace std; int main(void) { const int a1 = 40; const int* b1 = &a1; char* c1 = (char *)(b1); *c1 = 'A'; int *t = (int*)c1; cout << a1 << " " << *t << endl; cout << &a1 << " " << t << endl; return 0; } 

A saída para isso é:

 40 65 0xbfacbe8c 0xbfacbe8c 

Isso quase parece impossível para mim, a menos que o compilador esteja fazendo otimizações. Como ?

Este é o comportamento indefinido , você está modificando uma variável const para que você não tenha nenhuma expectativa quanto aos resultados. Podemos ver isso indo para o rascunho da seção padrão C ++ 7.1.6.1 O cv-qualifiers parágrafo 4 que diz:

[…] qualquer tentativa de modificar um object const durante seu tempo de vida (3.8) resulta em um comportamento indefinido.

e até fornece um exemplo:

 const int* ciq = new const int (3); // initialized as required int* iq = const_cast(ciq); // cast required *iq = 4; // undefined: modifies a const object 

Na definição padrão de comportamento indefinido na seção 1.3.24 , apresenta os seguintes possíveis comportamentos:

[…] O comportamento indefinido permissível varia de ignorar a situação completamente com resultados imprevisíveis, comportar-se durante a tradução ou execução do programa de uma maneira documentada característica do ambiente (com ou sem a emissão de uma mensagem de diagnóstico), para terminar uma tradução ou execução (com a emissão de uma mensagem de diagnóstico). […]

Seu código tem comportamento indefinido, porque você está modificando um object constante. Tudo pode acontecer, nada é impossível.

Quando você qualifica as variables const o compilador pode assumir algumas coisas e gerar código, isso funciona bem, desde que você respeite esse acordo e não o quebre. Quando você quebrou, você terá um comportamento indefinido.

Note que quando const é removido, funciona como esperado; aqui está um exemplo ao vivo .

Como já foi explicado por outros, modificar um valor const resulta em um comportamento indefinido e nada mais precisa ser dito – qualquer resultado é possível, incluindo um triggerste completo ou uma falha.

Se você está curioso para saber como surgiu esse resultado em particular , é quase certo que isso se deva à otimização. Desde que você definiu a como const , o compilador está livre para replace o valor 40 que você atribuiu a ele sempre que quiser; afinal de contas, seu valor não pode mudar, certo? Isso é útil quando você está usando a para definir o tamanho de um array, por exemplo. Mesmo no gcc, que tem uma extensão para matrizes de tamanho variável, é mais simples para o compilador alocar uma matriz de tamanho constante. Uma vez que a otimização existe, provavelmente é aplicada de forma consistente.