6 Réponses :


4
votes

pouvons-nous modifier la valeur d'un Const variable?

Oui, vous pouvez modifier une variable const à travers divers moyens: pirate de pointeur, moulages, etc ...
lire ensuite q!

est-ce code valide pour modifier la valeur d'un Const variable?

Non! Ce que cela vous donne est comportement indéfini .

Techniquement, votre exemple de code a un comportement non défini .
Le programme ne respecte pas la norme C une fois que vous modifiez le Const et peut donc donner tout résultat.

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 et le compilateur n'est pas nécessaire pour fournir un diagnostic pour celui-ci.

La norme C99 3.4.3 dit:

Comportement indéfini: 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.

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).


6 commentaires

Merci. Donc, je ne comprends pas ce que l'auteur a signifié? Si le comportement est en effet non défini, pourquoi enregistre nécessaire?


@Kirilenko registre 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 , vous ne pouvez pas modifier la variable prenant son adresse non plus, non? Est-ce différent pour le compilateur?


@Kirilenko vous peut jeter le const puis le modifier. Si vous êtes malveillant, vous ne vous souciez pas du fait que cela invoque UB. Avec enregistrer , 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 : 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 -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 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 Il est facilement détectable.)



1
votes

Le fragment de code invoque en effet un comportement indéfini.

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 de sorte que ... ub est invoqué à la place ... ? Comment est-ce préférable? Être franc, cela n'a pas de sens.


1 commentaires

@Umnyobe: Vous n'êtes pas obligé. Imo le texte cité est assez explicite.



1
votes

Je pense que l'auteur parle également de cette affaire, qui est un malentendu de const : xxx

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.


0 commentaires

2
votes

Votre code compile, mais il a un comportement non défini.

Le point de l'auteur est d'utiliser Const et enregistrer de sorte que le code ne compile plus: xxx


0 commentaires

11
votes

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
}


2 commentaires

A besoin d'une distribution, int * q = (int *) i; * q = 42; .


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 :)



0
votes

Je ne comprends pas comment nous pouvons modifier la valeur d'une variable Const par un pointeur. N'est-ce pas un comportement indéfini?


Oui, c'est un comportement indéfini:

Citation de C18, 6.7.3 / 7:

"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."

Mais simplement parce que le comportement n'est pas défini, cela ne signifie pas que vous potentiellement 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 vous avertit - qui est un gros problème. < / p>

Heureusement dans ce cas, lors de la compilation de Fe: xxx

Le compilateur lancera un avertissement:

Qualificateur d'initialisation de l'initialisation «Const» de type cible du pointeur [-WDCarded-Qualificateurs] (GCC)

ou

AVERTISSEMENT: initialisation 'int *' avec une expression de type 'const int *' rejetant les qualificatifs [-wincompatibles-pointer-ornonces-Types-Discards] (Clang)

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 Option bien sûr).


pouvons-nous modifier la valeur d'une variable const

Alors, oui - malheureusement. On peut effectivement modifier un objet const , mais vous ne devriez jamais le faire, ni intentionnellement ni par accident.

la méthode à utiliser Enregistrer Le mot-clé peut être efficace car l'adresse d'un registre 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.


0 commentaires