Resumindo, estou perguntando se o código a seguir invoca o UB somente se /* body */
de fato altera o valor de i
, ou também se não altera, em virtude da chamada da const
maybeChange
função não membro em um const
objeto.
// header.hpp
struct Foo {
int i;
void maybeChange();
};
void work(Foo const& foo);
// foo.cpp
#include "header.hpp"
void Foo::maybeChange() {
/* body */
}
// work.cpp
#include "header.hpp"
void work(Foo const& foo) {
const_cast<Foo&>(foo).maybeChange();
}
// main.cpp
#include "header.hpp"
Foo const foo{6};
int main() {
work(foo);
}
Vejo que o problema existe caso a modificação realmente ocorra, porque isso viola uma suposição legítima que o compilador pode fazer, ou seja, que o foo
objeto global não muda.
Mas, por outro lado, http://eel.is/c++draft/dcl.type.cv#4 não mostra nenhum exemplo de chamada de const
função não membro em const
objeto para o qual const
foi const_cast
ed away, mas isso não o modifica de fato, como no meu exemplo acima. Ele mostra exemplos triviais como
const int* ciq = new const int (3); // initialized as required
int* iq = const_cast<int*>(ciq); // cast required
*iq = 4; // undefined behavior: modifies a const object
onde a última linha realmente modifica o objeto *ciq
.
Chamar a função em si não é UB. Só há UB se você tentar modificar o valor de um dos membros ou do próprio objeto.
E se
foo
não fosse declaradoconst
, então não haveria nem UB se a função modificasse o objeto ou seus membros.É exatamente o mesmo que para parâmetros de função explícitos. Você pode visualizar o operando no lado esquerdo de
.
como um argumento implícito para um parâmetro implícito do tipoFoo&
. Ele se comporta principalmente da mesma forma que outros argumentos com essa interpretação.Conforme referenciado em sua pergunta, [dcl.type.cv]/4 é a única regra que resulta em UB devido a
const
ness e nada em seu exemplo a viola. O fato de não haver um exemplo adequado para isso no padrão não muda nada. Se você acha que isso pode ajudar no entendimento, você pode sugerir adicionar tal exemplo via editorial issue here , embora eu não saiba as políticas sobre exemplos ou tais sugestões.