comment éviter de changer la valeur de const en C

Bonjour, Je suis débutant dans le monde de la programmation, je veux savoir comment éviter de changer la valeur d’une variable const.

#include  int main() { const int i = 10; int * p = &i; *p = 20; printf("*p = %d\ni = %d\n", *p,i); printf("%u\n%u\n",&i, p); return 0; } 

ici, dans le programme ci-dessus, je reçois seulement un avertissement, mais aucune erreur alors que j’atsortingbue une valeur au champ const via un pointeur, mais lorsque j’imprime la sortie, ce n’est pas différent:

 *p = 20 i = 10 3210723532 3210723532 

alors quelle est l’utilité d’obtenir le pointeur sur const quand il ne peut pas changer.

La norme C utilise uniquement le terme “diagnostic”. Il n’y a pas de distinction entre avertissements et erreurs.

La conversion de const int * en int * sans transt est une violation de contrainte qui nécessite un diagnostic.

Cela le place dans la même catégorie qu’une erreur de syntaxe: votre code n’est pas un programme ISO C valide et le comportement n’est pas défini s’il est traduit et exécuté de toute façon.

Malheureusement, de nombreux compilateurs ne font pas la distinction entre les diagnostics requirejs et les diagnostics supplémentaires qu’ils ajoutent. Pis encore, ils ont parfois besoin de diagnostics sous forme d’avertissements. Ceci est autorisé: la norme C ne dit pas que les programmes nécessitant un diagnostic doivent être empêchés de traduction et d’exécution. En émettant un avertissement, un compilateur satisfait à l’exigence de diagnostic et c’est tout.

Un autre problème est que beaucoup de compilateurs C n’acceptent même pas le dialecte ISO C standard à moins d’y être invité, mais acceptent plutôt leur propre dialecte, qui peut avoir des extensions non conformes (c’est-à-dire non compatibles avec les versions antérieures).

Le compilateur GNU C comprend un dialecte C appelé GNU C 89, si vous ne lui donnez pas d’option dialecte.

Donc, paradoxalement, dans ce dialecte, il ne s’agit que d’un simple avertissement pour convertir const int * en int * sans casting, alors que certains programmes légaux C90 sont complètement rejetés.

Donc, fondamentalement, vous devez toujours comprendre comment contrôler le dialecte d’entrée de votre compilateur et suivre tous les avertissements, que vous devez comprendre par vous-même, s’il s’agit de véritables violations de la langue ou des caprices du compilateur. écrivains (“suggèrent des parenthèses autour de cette expression”).

Ce n’est pas une mauvaise idée de comstackr avec gcc -Wall -W -ansi (si vous programmez en C90; ou -std=c99 au lieu de ansi pour C99) et d’éviter tout avertissement. Pas même les stylistiques qui suggèrent des parenthèses supplémentaires et autres. Si vous n’êtes pas assez discipliné pour suivre les avertissements, ajoutez -Werror pour les transformer en erreurs qui échoueront dans votre construction. Certains recommanderaient également -pedantic .

Si vous suivez cette discipline, la subversion d’un const int ne se faufile pas dans votre base de code.

Tout d’abord, le compilateur donnera l’avertissement à cause du code int * p = &i;

et la valeur de i n’est pas modifiée, car la compilation optimise le code, j’utilise le gcc pour tester le code:

si j’utilise le gcc -O0 const.c -o const , O0 ne représente aucune optimisation du compilateur, le résultat est

 *p = 20 i = 20 1114013412 1114013412 

mais quand j’utilise le gcc -O2 const.c -o const , O2 représente l’optimisation du compilateur, le résultat est

 *p = 20 i = 10 1262279764 1262279764 

Ainsi, le compilateur sait que le type de i est const et remplace i par 10 au moment de la compilation, ce qui fait que le code devient

  printf("*p = %d\ni = %d\n", *p,10); 

Vous pouvez également utiliser gcc -S const.c pour consulter le code de l’assembly.

Le standard de langage C ne nécessite (presque) jamais que les compilateurs rejettent un code incorrect. Si vous écrivez quelque chose d’illégal et que le compilateur vous en avertit simplement, le compilateur a fait son travail en ce qui concerne le standard de langage C.

Vous devez prendre les avertissements du compilateur très au sérieux. Si votre code est compilé sans avertissements ni erreurs, il est probablement légal (ce qui ne signifie pas que cela fonctionnera réellement!).

Faites-en un #define place.

Les objects déclarés const ne sont pas constants au sens anglais du terme, ils sont “en lecture seule”.

 #include  int main() { #define I 10 int * p = &I; // illegal &I *p = 20; printf("*p = %d\nI = %d\n", *p,I); printf("%u\n%u\n",&I, p); // illegal &I return 0; }