Pergunta

Em C ++, tenho uma função que requer apenas acesso somente leitura a uma matriz, mas é declarado por engano como recebendo um ponteiro que não é consagrado:

size_t countZeroes( int* array, size_t count )
{
    size_t result = 0;        
    for( size_t i = 0; i < count; i++ ) {
       if( array[i] == 0 ) {
           ++result;
       }
    }
    return result;
}

E eu preciso chamá -lo para uma matriz const:

static const int Array[] = { 10, 20, 0, 2};

countZeroes( const_cast<int*>( Array ), sizeof( Array ) / sizeof( Array[0] ) );

Isso será um comportamento indefinido? Em caso afirmativo - quando o programa se deparará com o UB - ao fazer o const_cast e ligar para o functon ou ao acessar a matriz?

Foi útil?

Solução

Sim, é permitido (se perigoso!). É a gravação real para um const Objeto que incorre em comportamento indefinido, não o próprio elenco (7.1.5.1/4 [dcl.type.cv]).

Como as notas padrão em 5.2.11/7 [expr.const.cast], dependendo do tipo de objeto, uma tentativa de escrever através de um ponteiro que é o resultado de eliminar const pode produzir comportamento indefinido.

Outras dicas

Como seu código não modifica a matriz, e você disse ao compilador, sabe o que está fazendo usando o const_cast, você realmente ficará bem. No entanto, acredito que você está tecnicamente invocando um comportamento indefinido. É melhor consertar a declaração da função ou escrever e usar a versão segura para const.

Sim, você pode fazer isso. Não, não é um comportamento indefinido, desde que a função realmente não tente escrever na matriz.

O problema de const_cast é sempre o mesmo - ele permite que você "quebre as regras", assim como o lançamento de e de void* - Claro que você pode fazer isso, mas a pergunta é por que você deveria?

Nesse caso, é claro que está bem, mas você deve se perguntar por que não declarou size_t countZeroes( const int* array, size_t count ) em primeiro lugar?

E como uma regra geral sobre const_cast:

  1. Pode produzir difíceis de encontrar bugs
  2. Você está jogando fora o alimento const-const com o compilador
  3. Basicamente, você está transformando o idioma em um de nível inferior.

Usando const_cast em um objeto que é inicialmente definido como const é UB, portanto o comportamento indefinido ocorre imediatamente no ponto em que você liga const_cast.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top