2011-04-04 15 views
7

Si hago:¿Dónde está el comportamiento indefinido cuando se usa const_cast <>?

const char* const_str = "Some string"; 

char* str = const_cast<char*>(const_str); // (1) 

str[0] = "P"; // (2) 

dónde (en qué línea) es exactamente el comportamiento indefinido?

He estado buscando mucho para esto en SO, pero no he encontrado ninguna respuesta explícita y precisa (o al menos, ninguna que yo pudiera entender).

También relacionado: si uso una biblioteca externa que proporciona este tipo de función:

// The documentation states that str will never be modified, just read. 
void read_string(char* str); 

¿Está bien escribir algo como:

std::string str = "My string"; 

read_string(const_cast<char*>(str.c_str())); 

Desde que estoy seguro de que read_string() se nunca intenta escribir en str?

Gracias.

Respuesta

9

La línea (2) tiene un comportamiento indefinido. El compilador tiene la libertad de colocar constantes en la memoria de solo lectura (había una vez en Windows, esto habría sido un "segmento de datos") por lo que escribir en él podría provocar la terminación de su programa. O tal vez no.

Tener que alejar la constidad cuando llama a una función de biblioteca mal definida (parámetro no const que debería ser const) es, por desgracia, no inusual. Hazlo, pero mantén tu nariz.

+6

"Hazlo, pero mantén la nariz". Considere hacerlo una vez en una función de envoltura, para que todos los sitios de llamadas distribuidas puedan al menos evitar esa fealdad. –

+0

Muchas gracias por su respuesta. ¿Tiene alguna fuente para fortalecer su último reclamo? Estoy diseñando un contenedor de C++ en torno a OpenSSL (que desafortunadamente adolece de serias incoherencias en la interfaz) y me gustaría asegurarme de que mi código no sea la causa de un comportamiento indefinido. – ereOn

+2

estándar de C++ La sección 5.2.11 # 7 indica que una * operación de escritura * da como resultado un comportamiento indefinido. Las operaciones de lectura deberían ser seguras. –

-1

Está intentando modificar una cadena constante que el compilador puede haber puesto en una sección de solo lectura del proceso. Esto es mejor:

char str[32]; 
strcpy(str, "Some string"); 
str[0] = "P"; 
+0

Sin ofender, pero eso no responde exactamente mi pregunta: sé que es malo, y si mi intención es modificar una cadena, no la declararé 'const' en primer lugar. La verdadera pregunta es más: "¿Realmente tengo que copiar primero mi secuencia para usarla con una interfaz mal diseñada o el molde es aceptable?" – ereOn

+0

Como RobH ha señalado - está en línea (2) - la línea donde modifica el búfer que potencialmente está en la memoria de solo lectura. – trojanfoe

+1

@ereOn: el hecho de que C++ le permite escribir 'char * x =" abc "', y por lo tanto puede compilar y ejecutar código C antiguo sin un comportamiento indefinido, es evidencia de que no hay un comportamiento indefinido hasta que realmente se intente una escritura . –

Cuestiones relacionadas