2011-01-30 11 views
7

Duplicar posible:
Does the evil cast get trumped by the evil compiler?¿Cuál es el propósito del calificador const si puedo modificarlo a través de un puntero en C?

Hola,

Si puedo modificar una constante a través de un puntero, entonces ¿cuál es el propósito de la misma? A continuación se muestra el código:

#include <stdio.h> 
#include <stdlib.h> 

int main() 
{ 
const int a = 10; 
int *p = (int *)&a; 

printf("Before: %d \n", a); 
*p = 2; 
/*a = 2; gives error*/ 

printf("After: %d \n", *p); 

return 0; 
} 

SALIDA:

Antes: 10
Después: 2
Pulse cualquier tecla para continuar. . .

mediante Visual Studio 2008.

+3

Ver [¿El malvado reparto es vencido por el malvado compilador?] (Http://stackoverflow.com/questions/712334/does-the-evil-cast-get-trumped-by-the-evil- compilador). Este es [comportamiento indefinido] (http://www.catb.org/jargon/html/N/nasal-demons.html). – ephemient

+0

Ahora compilar con optimizaciones. – GManNickG

Respuesta

12

La razón podría modificar el valor se debe a que usted hizo un encasillado puntero que se despojó de la const Ness:

int *p = (int *)&a; 

Este typecasts un const int* (es decir, &a) a int *, lo que le permite modificar libremente la variable. Normalmente, el compilador le advertiría sobre esto, pero el tipo de transmisión explícito suprimió la advertencia.

La razón principal detrás de const en absoluto es evitar que se modifiquen accidentalmente algo que usted prometió no hacerlo. No es sacrosanta, como hemos visto, y se puede desechar const ness con impunidad, tanto de la misma manera que usted puede hacer otras cosas inseguras como la conversión de punteros a enteros o viceversa. La idea es que debe intentar lo mejor para no meterse con const, y el compilador le avisará si lo hace. Por supuesto, agregar un yeso le dice al compilador "Sé lo que estoy haciendo", por lo que en su caso lo anterior no genera ningún tipo de advertencia.

9

Si puedo modificar una constante a través de un puntero entonces ¿cuál es el propósito de que ? a continuación es código:

Este es un comportamiento indefinido y debe evitarse a toda costa:

§ C99 6.7.3p5

Si se hace un intento de modificar un objeto definida con una const cualificado tipo a través del uso de un lvalue con el tipo no const-calificado, el comportamiento no está definido.

+1

"debe evitarse a toda costa" Pero, ¿qué sucede si una persona dice que me lastimarían si no lo hiciera? :( – GManNickG

+6

@GMan Sacrificarse para evitar UB garantiza un lugar en Coding Nirvana donde la palabra clave 'static' tiene solo un significado y se conoce la fecha de lanzamiento de Perl 6. – SiegeX

+0

¿Quiere decir que se molestan con idiomas que no son Lisp en Coding Nirvana? ? –

Cuestiones relacionadas