Está utilizando const_cast para el acceso de sólo lectura a un objeto constante permitido?
-
20-09-2019 - |
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
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
:
- Se puede producir difícil de encontrar errores
- Usted está tirando la const-acuerdo con el compilador
- 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
.