6 Réponses :
pouvons-nous modifier la valeur d'un Const code> variable? strong> p> blockQuote>
Oui, vous pouvez modifier une variable
const code> à travers divers moyens: pirate de pointeur, moulages, etc ...
lire ensuite q! em> p>est-ce code valide pour modifier la valeur d'un
Const code> variable? strong> p> blockQuote>
Non! Ce que cela vous donne est
comportement indéfini fort>. P> Techniquement, votre exemple de code a un comportement
non défini fort>.
Le programme ne respecte pas la norme C une fois que vous modifiez leConst code> et peut donc donner tout résultat. P>
Notez qu'un comportement indéfini ne signifie pas que le compilateur doit signaler la violation en tant que diagnostic. Dans ce cas, votre code utilise le piratage du pointeur pour modifier un
const code> et le compilateur n'est pas nécessaire pour fournir un diagnostic pour celui-ci. P>
La norme
C99 3.4.3 forte> dit: p>
Comportement indéfini: strong> Comportement, lors de l'utilisation d'une construction de programme non-sport ou erronée ou de données erronées, pour lesquelles cette norme internationale n'impose aucune exigence. P> Remarque Le comportement non défini possible va d'ignorer complètement la situation avec des résultats imprévisibles, de se comporter lors de la traduction ou de l'exécution du programme de manière documentée caractéristique de l'environnement (avec ou sans la délivrance d'un message de diagnostic), de mettre fin à une traduction ou à une exécution (avec la délivrance d'un message de diagnostic). P> blockQuote>
Merci. Donc, je ne comprends pas ce que l'auteur a signifié? Si le comportement est en effet non défini, pourquoi enregistre code> nécessaire?
@Kirilenko registre code> signifie que vous ne pouvez pas prendre l'adresse, il ne peut donc pas être modifié par les moyens ci-dessus.
@Daniel Fischer: Mais avec une variable const code>, vous ne pouvez pas modifier la variable prenant son adresse non plus, non? Est-ce différent pour le compilateur?
@Kirilenko vous peut i> jeter le const code> puis le modifier. Si vous êtes malveillant, vous ne vous souciez pas du fait que cela invoque UB. Avec
enregistrer code>, le code prenant son adresse ne doit même pas compiler.
Ok, c'est ce que je cherchais. La différence est l'interprétation du comportement par le compilateur. Cela dépend du compilateur: Dans tous les cas, l'utilisateur est faux. Mais ce n'est pas comment fonctionne restreindre code>: si l'utilisateur envoie deux pointeurs aliasés à la fonction, il n'obtiendra pas une erreur du compilateur ...
@Kirilenko UB ne nécessite pas de diagnostic. Si vous cassez la promesse que vous avez faite par restreindre code> -qualifier une variable, c'est UB. Et pour détecter cela, le compilateur aurait besoin d'une analyse de dépendance exhaustive. Prendre l'adresse d'une variable avec
registre code> La classe de stockage est une violation de contrainte facilement détectable, d'où un diagnostic est requis. (Je pense que cela a été fait une violation de contrainte et non l'UB parce que i> Il est facilement détectable.)
Le fragment de code invoque en effet un comportement indéfini. P>
Je ne suis pas vraiment sûr de ce que le point de l'auteur est: Afin de ne pas laisser "code de l'étranger", changez la valeur de la variable que vous le rendez const code> de sorte que ... ub est invoqué à la place ... ? Comment est-ce préférable? Être franc, cela n'a pas de sens. P>
@Umnyobe: Vous n'êtes pas obligé. Imo le texte cité est assez explicite.
Je pense que l'auteur parle également de cette affaire, qui est un malentendu de la variable elle-même n'est pas constante, mais le pointeur est . Le code malveillant peut convertir en un pointeur régulier et modifier légalement la variable ci-dessous. p> p> const code>:
Votre code compile, mais il a un comportement non défini.
Le point de l'auteur est d'utiliser Const code> et strud>
enregistrer code> de sorte que le code ne compile plus: p>
Le point de l'auteur est que déclarer une variable avec registre code> Classe de stockage vous empêche de prendre son adresse. Il ne peut donc pas être transmis à une fonction qui pourrait modifier sa valeur en diffusant
const code>.
void bad_func(const int *p) {
int *q = (int *) p; // casting away const
*q = 42; // potential undefined behaviour
}
void my_func() {
int i = 4;
const int j = 5;
register const int k = 6;
bad_func(&i); // ugly but allowed
bad_func(&j); // oops - undefined behaviour invoked
bad_func(&k); // constraint violation; diagnostic required
}
A besoin d'une distribution, int * q = (int *) i; * q = 42; code>.
J'ai suscité ceci avant de donner les détails, je voudrais éteindre une fois encore si possible. BTW je voulais utiliser le cas "// laid mais autorisé" mais je n'étais pas sûr :)
Je ne comprends pas comment nous pouvons modifier la valeur d'une variable code> Const code> par un pointeur. N'est-ce pas un comportement indéfini? P>
Oui, c'est un comportement indéfini: p>
Citation de C18, 6.7.3 / 7: P>
"Si une tentative est faite de modifier un objet défini avec un type de Cons-qualifié grâce à une utilisation d'un type de lvalue avec type non-qualifié, le comportement est indéfini." EM> P> BlockQuote>
Mais simplement parce que le comportement n'est pas défini, cela ne signifie pas que vous potentiellement em> ne peut pas faire cela. Autant que je puisse penser, c'est bien le cas, que le compilateur sera, la plupart des temps de votre programme contenant tout type de comportement non défini,
non strong> vous avertit - qui est un gros problème. < / p> Heureusement dans ce cas, lors de la compilation de Fe: P>
xxx pré> Le compilateur lancera un avertissement: P>
Qualificateur d'initialisation de l'initialisation «Const» de type cible du pointeur [-WDCarded-Qualificateurs] (GCC) P> blockQuote>
ou p>
AVERTISSEMENT: initialisation 'int *' avec une expression de type 'const int *' rejetant les qualificatifs [-wincompatibles-pointer-ornonces-Types-Discards] (Clang) P> blockquote>
Mais malgré le fait que le code contient des pièces qui causent un comportement non défini et que vous ne pouvez jamais être sûr de ce qu'il imprimera sur une exécution, vous obtenez ce programme malveillant compilé (sans
-WerRor code> Option bien sûr). p>
pouvons-nous modifier la valeur d'une variable code> const code> p> BlockQuote>
Alors, oui - malheureusement. On peut effectivement modifier un objet
const code>,
mais strong> vous ne devriez jamais le faire, ni intentionnellement ni par accident. P> la méthode à utiliser
Enregistrer CODE> Le mot-clé peut être efficace car l'adresse d'un
registre code> la variable marquée n'a pas son adresse prise - signifie que vous ne pouvez pas affecter un pointeur avec l'adresse de la variable relative ni la transmettre à un fonction comme argument du type de pointeur correspondant. P> blockQuote>