Où une variable si la réponse est le segment de code, alors comment le code suivant fonctionne-t-il ?? p> Ce code fonctionne bien. .. Comment il est possible de changer une mémoire en lecture seule? Comment ça se passe vraiment stocké? S'il vous plaît expliquer cela en détail. P> p> const code> est-il stocké exactement et comment change-t-il? Dites par exemple:
9 Réponses :
Cela ne devrait vraiment pas fonctionner. P>
Les constantes ne sont généralement pas stockées nulle part. Ils sont étendus en ligne. P>
Il est possible que votre compilateur soit gentil avec vous et vous donnant un lieu de mémoire à modifier, mais normalement, c'est impossible. P>
Quels avertissements obtenez-vous? J'imagine que vous devez obtenir un peu ... p>
Ils ont stocké des autres variables, mais peuvent être remplacées par des lignes en ligne par optimiseur.
Je ne sais pas où il est stocké, car c'est défini par la mise en œuvre, mais votre code entraîne un comportement non défini. p>
C'est totalement à la hauteur du rédacteur du compilateur Qu'est-ce qui arrive à la const, et il variera en fonction de l'optimisation que vous demandez. P>
Dans votre premier exemple, les constantes ne sont jamais utilisées pour que le compilateur ne les ignorera probablement pas complètement. p>
Dans votre deuxième exemple Lorsque vous utilisez "adresse", il doit le stocker quelque part - probablement au début de la pile. p>
C est conçu pour remplacer les instructions de langage de l'assemblage, et pour la rédaction de code de type OS Kernal et du pilote de périphérique, vous permet de faire toutes sortes de choses et vous assume que vous savez ce que vous faites lorsque vous commencez à jouer avec des pointeurs. P>
Le compilateur détermine si l'adresse de la constante est nécessaire. Si ce n'est pas le cas, il est (généralement) entré en ligne dans le segment de code, car c'est (généralement) plus rapide que la mémoire de référencement. P>
Si l'adresse est nécessaire, la constante est stockée comme s'il s'agissait d'une variable non constituée dans la portée actuelle (relativement en fonction du compilateur). En d'autres termes, Global Consts est généralement stocké dans votre segment de données, fonction (paramètre ou déclaré) constons généralement être stocké sur la pile. P>
pense à cela comme une variable de registre. C'est dans votre registre de votre CPU, si vous connaissez cela. C'est dans votre inscription de votre CPU jusqu'à ce que vous ayez besoin de son adresse. Ensuite, il est mis dans un espace adressable. P>
La vraie question est l'initialisation - si vous avez besoin de son adresse et est donc réellement allouée, alors où est-il initialisé? Il y a quelque chose pour vous de réfléchir. P>
Le mot-clé Contrairement à La raison pour laquelle l'extrait de code que vous avez posté "WORKS" est parce que l'opérateur unaire edit: strong> Voir aussi: http: // publications.gbdirect.co.uk/c_book/chapter8/const_and_volatile.html p>
Regardons ce que l'on veut dire quand const
est utilisé. C'est vraiment assez simple:
consiste signifie que quelque chose n'est pas
modifiable, donc un objet de données qui est
déclaré avec const dans une partie de son
Les spécifications de type ne doivent pas être
attribué à de quelque manière que ce soit pendant la course
d'un programme. Il est très probable que
La définition de l'objet sera
contenir un initialiseur (sinon,
Puisque vous ne pouvez pas l'affecter, comment
cela aurait-il jamais une valeur?), mais cela
n'est pas toujours le cas. Par exemple,
Si vous accédez à un port matériel
à une adresse mémoire fixe et promise
seulement à lire, alors ce serait
déclaré être const mais pas
initialisé. const code> indique une variable en lecture seule (c'est-à-dire que, ne peut pas être modifiée au moment de l'exécution). Il n'indique pas une constante de temps de compilation. Strong> Par conséquent, tous les attributs habituels des variables s'appliquent; Plus précisément, il s'agit d'un espace de stockage adressable alloué. P>
#define code>, votre constante n'est pas nécessairement em> inline par le compilateur. Au contraire, le compilateur créera un symbole correspondant à votre déclaration
const code> dans le fichier d'objet afin de pouvoir être accessible à partir d'autres fichiers de code - rappelez-vous que les objets
const code> ont une liaison externe par Par défaut en C (Bien que certains compilateurs feront toujours en ligne la valeur constante dans le fichier dans lequel il est défini). p>
& code> peut être appliqué à n'importe quelle lvalue, qui comprend un objet
const code>. Bien que le comportement soit indéfini, je soupçonne que votre compilateur détecte cette utilisation et que votre déclaration code> const code> est donnée dans l'espace d'adresses et ne l'affiche pas, même dans le fichier, il est déclaré. p>
Prendre l'adresse d'un
objet de données d'un type qui n'est pas
const et le mettre dans un pointeur à
la version de Const-qualifiée de la
même type est à la fois sûr et explicitement
permis; Vous pourrez utiliser le
pointeur pour inspecter l'objet, mais pas
Modifiez-le. Mettre l'adresse d'un
Const Type dans un pointeur sur le
Type non qualifié est beaucoup plus
dangereux et par conséquent interdit
(Bien que vous puissiez entrer cela par
en utilisant une distribution). Par exemple ... P>
blockQuote>
C'est une excellente réponse. Je n'ai bien compris que ce que const code> en C lorsque j'ai rencontré une variable déclarée
const volatile code> (c'était un registre matériel). Après mon moment initial WTF, j'ai réalisé que
const code> signifie simplement que vous b>, le programmeur, promettez de ne pas le changer. Si vous vous attendez à ce qu'il change par d'autres moyens, vous avez besoin du
volatile code>. Mais il n'est pas interprété par le compilateur en tant que constante de temps de compilation (comme dans
C ++ code>, je pense).
@Detly, une variable Const ne peut pas apparaître dans un endroit où une expression constante est synontiquement (ce qui est effectivement autorisé pour certains d'entre eux en C ++). Le compilateur peut toujours le considérer comme une constante de temps de compilation à d'autres fins - et le fait probablement.
@Aprogrammer - En effet, c'est une meilleure phrasalisation. Le compilateur ne peut pas le considérer comme une constante de temps de compilation (ou une constante d'exécution) si elle est également déclarée volatile.
Le deuxième code ne devrait pas compiler du tout. Et les compilateurs que j'ai ici sont d'accord: GCC donne une erreur avec des erreurs -pedantic (dont le but est de se transformer en erreur de diagnostics obligatoires que Historiquement GCC n'a pas considéré comme une erreur), XLC donne une erreur aussi. P >
Si vous souhaitez une référence: 6.3.16.1 dans la norme C90 décrit lorsqu'une attribution est possible: p>
Les deux opérandes sont des pointeurs vers des versions qualifiées ou non qualifiées de types compatibles, et le type pointé à gauche a tous les qualificatifs du type pointé vers le droit p> blockQuote>
et C99 comme une contrainte similaire. p>
Lorsque vous déclarez (non-externe, non-argument) et initialisez la variable comme standard n'apparte pas, que devrait-il arriver si vous essayez d'écrire const (cela s'appelle «comportement indéfini»), de sorte que tout peut se produire: il peut être écrit, non écrit, causer une exception, suspendre ou quelque chose d'autre que vous ne pouvez pas imaginer. C non aussi paranoïaque que, disons, ADA, et tout comportement non couché est à programmer, pas compilateur ou RTL. P>
Comme beaucoup l'indiquent, il est inliné dans la plupart des cas (si le compilateur sache qu'en ligne), mais conserve toujours les attributs des variables, tels que l'adresse (et vous pouvez obtenir un pointeur), la taille. Si toutes les déclarations de const sont éliminées et que le stockage pour const sera également éliminé par Compiler (s'il est statique ou local) ou de la liaison (si elle est globale). P>
Remarque, les pointeurs locaux peuvent également être éliminés si leurs emplacements peuvent être calculés en temps de compilation. Les écrivies également aux variables locales peuvent être éliminées si elles ne sont pas lues après cela. Votre extrait ne peut avoir aucun code du tout. P>
La variable locale automatique peut être compilée dans le stockage statique si le compilateur prouve qu'une seule instance de celle-ci est nécessaire. Comme const n'est pas modifiable, il est également compilé dans le stockage statique, mais peut être éliminé comme indiqué ci-dessus. P>
Dans tous vos exemples, tous les constons peuvent d'abord être mis de stockage statique (Const Section), puis facilement éliminés. P> const code>, cela signifie que la variable n'est pas réelle. Donc, le compilateur est libre de le placer à la seule section. Bien que cela puisse être modifiable physiquement (si le matériel le permet). Ou non modifiable, s'il est protégé par MMU ou placé dans la ROM dans l'application autonome. P>
Modification de votre code pour imprimer la valeur:
#include <stdio.h> main() { const int j=20; int *p; p=&j; (*p)++; printf("%d\n", j); return 0 ; }
par la norme C ( N1256 brouillon): p>
6.7.3 Type Qualificateurs B>
...
3 Les propriétés associées à des types qualifiés ne sont significatives que pour les expressions que sont des lvalues. 114) sup>
...
5 Si une tentative est faite pour modifier un objet défini avec un type de Cons-qualifié via une utilisation d'une lvalue avec type non qualifié non constitué, le comportement est indéfini. Si une tentative est fait pour se référer à un objet défini avec un type qualifié volatile grâce à une utilisation d'un lvalue Avec type qualifié non volatile, le comportement est indéfini. 115) sup>
...
114) La mise en œuvre peut placer un objetconst code> qui n'est pas
volatile code> dans une région en lecture seule de espace de rangement. De plus, la mise en œuvre n'a pas besoin d'allouer de stockage pour un tel objet si son adresse est jamais utilisé.
115) Ceci s'applique à ces objets qui se comportent comme s'ils étaient définis avec des types qualifiés, même s'ils sont jamais réellement défini comme des objets du programme (comme un objet à une entrée / sortie mappée de mémoire adresse). blockQuote>En bref, un objet
const code> objet qualifié peut être stocké dans une zone différente de la non-
const code> objets qualifiés, mais pas nécessairement . p>
Le qualificatif
const code> est une instruction au compilateur pour rejeter le code qui tente de modifier directement cet objet; Les tentatives de modification de l'objet indirectement (comme vous le faites dans la deuxième extrait de code) entraînent un comportement non défini, ce qui signifie tout résultat em> est possible. p>
Avez-vous vérifié ceci: Stackoverflow.com/questions/3801557/... ?
Je peux vous assurer que votre segment de 2e code est comportement indéfini b>
Je crois que la plupart des compilateurs modernes donneraient un avertissement lors de la transmission de la ligne "p = & j" avertissant des différents qualificateurs de const, car vous attribuez un pointeur à Const Int à un pointeur à int. Donc, la morale de l'histoire est la suivante: toujours utiliser -werror