Eu sei que isso (void)0
é um no-op em C/C++. No entanto, quando eu estava olhando o código em <cassert>
, eu vi void (0)
.
Acho que é algo como int (0)
ou int{0}
. Eu também tentei void{}
e funciona. Parece que esta é uma inicialização zero para void
.
Mas void
é um tipo incompleto , como é que o compilador não reclama? ( g++-14 -std=c++23 -Wall
)
Ambos
void(0)
evoid{}
são expressões de conversão de tipo explícito no estilo de função no padrão, e a semântica é definida da seguinte forma,Para
void(0)
, a primeira frase se aplica, e a expressão é semanticamente equivalente a(void)0
, que você já conhece. Para expandir ainda mais, isso é equivalente astatic_cast<void>(0)
onde o padrão faz um caso especial para em expr.static.cast . Para , a segunda frase entra em jogo, e o padrão especifica explicitamente que nenhuma inicialização é realizada. Em ambos os casos, não há "inicialização de tipo incompleto" envolvida, e isso explica por que o compilador não reclama.cv
void
void{}
Quando você escreve
T(E)
em C++ ondeT
é um tipo eE
uma única expressão, isso é chamado de expressão de conversão de estilo funcional e é exatamente equivalente à expressão de conversão de estilo antigo(T)E
em termos de semântica.Então
void(0)
é exatamente equivalente a(void)0
.(Existem algumas diferenças de análise em termos de precedência de operadores e o que a gramática permite
T
conter exatamente.)