Atualização: como parece ser um bug do compilador, enviei um relatório à Microsoft .
A saída do código a seguir me surpreende. Minha expectativa é que ele Inner
teria num1
inicializado em 10 (como está) e depois num2
seria inicializado, copiando num1
o valor de 10. Portanto, a saída seria 10 10
. Em vez disso, eu entendo 10 4
.
#include <iostream>
struct Inner {
uint64_t num1{10};
uint64_t num2{num1};
};
struct Outer {
uint64_t a{};
Inner inner{};
};
Outer makeOuter() {
return {.a = 4};
}
int main(int argc, char* argv[]) {
auto outer = makeOuter();
std::cout << outer.inner.num1 << " " << outer.inner.num2 << std::endl;
return 0;
}
num2
parece copiar memória não inicializada (ou do endereço errado?). Ele recebe o valor do Outer
membro de a
, seja ele 4 ou 0xFFFFFFFFFFFFFFFF.
O compilador é MSVC 19.37.32825.0. Compile, por exemplo, executando cl main.cpp /std:c++latest /EHsc /O2 /link /out:program.exe
.
Com clang++ ou g++, obtenho o resultado esperado, 10 10
. Bug do compilador ou meu mal-entendido?
Os efeitos de algumas outras mudanças:
- Adicionar um construtor
Inner() {}
àInner
-> saída torna-se10 10
- Mudar
Inner inner{}
paraInner inner{11, 12}
-> a saída torna-se11 12
(esperada) - Mudar
Inner inner{}
paraInner inner{11}
-> saída torna-se11 4
- Retornar
{}
em vez de{.a = 4}
-> a saída torna-se10 10
- Criando
Inner inner{}
diretamentemain
e imprimindo seus membros -> a saída torna-se10 10