Pregunta

En C ++ Tengo una función que sólo requiere acceso de sólo lectura a una matriz, pero se declara erróneamente como la recepción de un puntero no constante:

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;
}

y tengo que llamarlo para una matriz const:

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

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

¿Esto será indefinido comportamiento? Si es así - cuando el programa se ejecute en UB - al hacer la const_cast y llamar a la functon o cuando se accede a la matriz

¿Fue útil?

Solución

Sí, se permite (si es peligroso!). Es la escritura real de un objeto const que incurre en un comportamiento indefinido, no el propio molde (7.1.5.1/4 [dcl.type.cv]).

Como las notas estándar en 5.2.11 / 7 [expr.const.cast], dependiendo del tipo del objeto de un intento de escribir a través de un puntero que es el resultado de la fundición de distancia const puede producir un comportamiento indefinido.

Otros consejos

Debido a que su código no modifica la matriz, y le dijo que el compilador sabe lo que está haciendo mediante el uso de la const_cast, en realidad se va a estar bien. Sin embargo, creo que está invocando técnicamente un comportamiento indefinido. Es mejor conseguir la declaración de función fija, o escribir, declarar y utilizar la versión const-seguro del mismo.

Sí, se puede hacer eso. No, no está definido el comportamiento, siempre y cuando la función verdaderamente no intenta escribir en la matriz.

El problema de const_cast es siempre la misma - que le permite "romper las reglas", al igual que la fundición hasta y desde void* - Seguro que se puede hacer eso, pero la pregunta es ¿para qué?

En este caso es por supuesto bien, pero usted debe preguntarse por qué no se declara size_t countZeroes( const int* array, size_t count ) en el primer lugar?

Y como regla general sobre const_cast:

  1. Se puede producir difícil de encontrar errores
  2. Usted está tirando la const-acuerdo con el compilador
  3. Básicamente que está girando el idioma a un nivel inferior.

El uso de const_cast sobre un objeto que se define inicialmente como const es UB, por lo tanto el comportamiento indefinido se produce inmediatamente en el punto de llamar const_cast.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top