2009-04-21 9 views
2

Je le morceau de code suivant:Modification de la valeur d'un pointeur const

 
void TestFunc(const void * const Var1, const float Var2) 
{ 
    *(float*)Var1 = Var2; 
} 

On dirait que je suis en train de changer la valeur de la const objet les points de const pointeur (Dentranchante thanks), qui ne devrait pas être autorisé. Le fait est qu'aucun des compilateurs que j'ai essayés n'a émis d'avertissement. Comment est-ce possible?

Répondre

10

Comme d'autres ont mentionné, le casting supprime le « constness » de la destination dans la mesure où l'expression est concerné. Lorsque vous utilisez un cast, le compilateur traite l'expression en fonction de la distribution - tant que le cast lui-même est valide (et les lancers de style C sont à peu près le gros marteau). C'est pourquoi vous n'obtenez pas d'erreur ou d'avertissement. Vous dites essentiellement au compilateur: «Taisez-vous, je sais ce que je fais, c'est comme ça que vous devriez traiter les choses». En fait, les distributions sont probablement le moyen n ° 1 pour les programmeurs d'obtenir que le compilateur arrête d'émettre des avertissements.

Votre expression d'affectation peut ou peut ne pas être un comportement non défini. Il est permis de rejeter la constellation si l'objet effectivement pointé n'est pas const.

Cependant, si l'objet pointé est const, alors vous avez un comportement non défini.

void TestFunc(const void * const Var1, const float Var2) 
{ 
    *(float*)Var1 = Var2; 
} 


int 
main(void) 
{ 
    float x = 1.0; 
    const float y = 2.0; 

    TestFunc(&x, -1.0); // well defined (if not particularly great style) 
    TestFunc(&y, -2.0); // undefined behavior 

    return 0; 
} 

Vous fouler les eaux dangereuses ...

En général (je suis sûr qu'il ya des exceptions), coulée de sorte que les expressions traitent les objets tels qu'ils sont vraiment est pris en charge, le comportement bien défini C/C++.

Ce comportement particulier est couvert dans les normes pour la plupart par des déclarations que la modification d'un objet const par un casting (ou quelque chose) qui supprime le qualificatif const est indéfini. L'inférence est que faire la même chose pour un objet non-const n'est pas indéfini. Un exemple donné dans la norme C++ le rend clair.

C90 6.5.3 - Type Qualifiers (C99 6.7.3):

Si une tentative de modifier un objet défini avec un type const qualifié par l'utilisation d'un lvalue avec des non-const type -qualifié, le comportement est indéfini.

7.1.5.1 C++ Les cv-qualifiés

Un pointeur ou une référence à un type de cv qualifié ne doivent pas en fait point ou se référer à un objet cv qualifié, mais elle est traitée comme si elle Est-ce que; un chemin d'accès qualifié const ne peut pas être utilisé pour modifier un objet même si l'objet référencé est un objet non-const et peut être modifié via un autre chemin d'accès. [Note: les qualificatifs cv sont pris en charge par le système de type, de sorte qu'ils ne peuvent pas être subvertis sans conversion (5.2.11). ]

Sauf qu'un membre de classe a été déclaré mutable (7.1.1) peut être modifié, toute tentative de modification d'un objet const au cours de sa vie (3.8) entraîne un comportement indéfini.

...

[Exemple:

...

int i = 2;   //not cv-qualified 
const int* cip;  //pointer to const int 
cip = &i;    //OK: cv-qualified access path to unqualified 
*cip = 4;    //ill-formed: attempt to modify through ptr to const 

int* ip; 
ip = const_cast<int*>(cip); //cast needed to convert const int*to int* 
*ip = 4;      //defined: *ip points to i, a non-const object 

const int* ciq = new const int (3); //initialized as required 
int* iq = const_cast<int*>(ciq);  //cast required 
*iq = 4;        //undefined: modifies a const object 
+0

Merci pour l'explication détaillée. Avez-vous une référence où cela est documenté pour le langage C? Tout ce que je peux trouver, c'est des références à const_cast en C++. – cschol

+1

J'ai ajouté le matériel pertinent des normes. –

+0

Je l'apprécie. Merci beaucoup! – cschol

1

Le casting est légal, mais le comportement est indéfini.

+0

Cela semble être une réponse déroutante pour moi. L'utilisation de la conversion peut être ou non un comportement indéfini, en fonction de son utilisation. –

2

Vous modifiez l'objet les points de pointeur, pas la valeur du pointeur. La distribution de type C agit comme une const_cast et supprime le modificateur const du pointeur. Le compilateur n'a plus rien à se plaindre.

Questions connexes