Guardate un po
Questa è una variabile costante.codice:const int a = 10;
Come può una variabile essere anche costante???
Guardate un po
Questa è una variabile costante.codice:const int a = 10;
Come può una variabile essere anche costante???
"Se proprio devono piratare, almeno piratino il nostro." (Bill Gates)
"Non è possibile che 2 istituzioni statali mi mettano esami nello stesso giorno." (XWolverineX)
http://xvincentx.netsons.org/programBlog
Beh ... veramente sei tu che hai scritto "variabile costante".
Quella e' solamente una costante.
Sbagliato! È a tutti gli effetti una variabile. Essendo dichiarata const, sarà poi il compilatore, durante la compilazione, che dovrà controllare che non vengano fatti assegnamenti a quella variabile.Originariamente inviato da oregon
Beh ... veramente sei tu che hai scritto "variabile costante".
Quella e' solamente una costante.
Se scrivo:
il compilatore ha sicuramente qualcosa da obiettare.codice:#include <stdio.h> int main (void) { const int a = 10; printf ("a = %d\n", a); a = 20; printf ("a = %d\n", a); return 0; }
La cosa curiosa è che ci sono differenze tra i vari compilatori. Con il VC++, il compilatore segnala un errore: "error C2166: l'elemento l-value specifica un oggetto const". Mentre con il gcc su linux, il compilatore mi segnala un semplice warning "warning: assignment of read-only variable `a'", generando comunque l'eseguibile che, una volta lanciato, stampa:
Comunque se uno volesse "fare il furbo", può sempre modificare una variabile const usando un puntatore:codice:a = 10 a = 20
In questo caso non ci sarebbe alcun warning o errore da parte del compilatore e il programma stampa quindi: a = 20codice:#include <stdio.h> int main (void) { const int a = 10; int *pa; pa = (int*) &a; *pa = 20; printf ("a = %d\n", a); return 0; }
Questo a dimostrazione che una variabile dichiarata const è ancora sempre una variabile a tutti gli effetti, con un suo indirizzo e con un suo valore.
No ... sbagli tu a dire che e' "a tutti gli effetti " una variabile.Originariamente inviato da andbin
Sbagliato! È a tutti gli effetti una variabile.
Se lo fosse, ne potresti modificare il valore come per le variabili ovvero
a = 6;
ma non puoi farlo. Non e' quindi una variabile "a tutti gli effetti".
E' una costante, di diverso tipo rispetto ad una costante dichiarata con il preprocessore ma pur sempre una costante.
Esatto. Proprio perche' non e' una variabile e il compilatore lo ricorda al programmatore distratto.Originariamente inviato da andbin
Essendo dichiarata const, sarà poi il compilatore, durante la compilazione, che dovrà controllare che non vengano fatti assegnamenti a quella variabile.
Mi sembra che il comportamento di VC++ sia piu' corretto.Originariamente inviato da andbin
Se scrivo:
il compilatore ha sicuramente qualcosa da obiettare.codice:#include <stdio.h> int main (void) { const int a = 10; printf ("a = %d\n", a); a = 20; printf ("a = %d\n", a); return 0; }
La cosa curiosa è che ci sono differenze tra i vari compilatori. Con il VC++, il compilatore segnala un errore: "error C2166: l'elemento l-value specifica un oggetto const". Mentre con il gcc su linux, il compilatore mi segnala un semplice warning "warning: assignment of read-only variable `a'", generando comunque l'eseguibile che, una volta lanciato, stampa:
codice:a = 10 a = 20
Se l'oggetto e' const, non puo' essere modificato come fosse una variabile.
Questa non e' una "furbizia".Originariamente inviato da andbin
Comunque se uno volesse "fare il furbo", può sempre modificare una variabile const usando un puntatore:
In questo caso non ci sarebbe alcun warning o errore da parte del compilatore e il programma stampa quindi: a = 20codice:#include <stdio.h> int main (void) { const int a = 10; int *pa; pa = (int*) &a; *pa = 20; printf ("a = %d\n", a); return 0; }
Questo a dimostrazione che una variabile dichiarata const è ancora sempre una variabile a tutti gli effetti, con un suo indirizzo e con un suo valore.
Stai solamente "cambiando le regole" dicendo semplicemente al compilatore che, in quell'occasione, ovvero nell'assegnazione
pa = (int*) &a;
deve considerare a come una variabile di tipo int e non const int.
Ovvero, in quel momento, quell'oggetto non e' una costante ma una variabile (ma solo in quel momento) ... ed e' cio' che differenzia questo oggetto da una costante definita con il preprocessore.
Se cambi le indicazioni che hai dato in precedenza, non stai trattando piu' una costante e quindi il discorso cade.
Infatti, per ottenere realmente l'indirizzo della costante "senza cambiare le carte in tavola" dovresti scrivere
const int a = 10;
const int *pa;
pa=&a;
e a questo punto non potresti fare
*pa=20;
Secondo me la faccenda è più sottile e complessa di quanto sembri...
Premettendo che neanch'io sono d'accordo sul fatto che una costante si possa modificare, già il fatto che ciò sia possibile, pur se non corretto, (sia perchè il compilatore scelto lo permetta sia utilizzando trucchetti tipo i puntatori), vuol dire che in effetti quella considerata non è una costante, ma piuttosto una variabile mascherata da costante.
In altre parole, in qualche modo le costanti, a livello implementativo, a quanto pare non sono tali.
Il problema, piuttosto, è scrivere compilatori coerenti con sè stessi: se dichiari costante un valore, questo deve restare tale, nel senso che il compilatore non deve permettere di modificarlocon puntatori nè tantomeno con normali assegnazioni VVoVe:
Un buon proposito per un compilatore migliore, insomma...
Svegliati, Neo. Matrix ti possiede...
E poi sei sicuro che verrebbe visualizzato 20 ?Originariamente inviato da andbin
Comunque se uno volesse "fare il furbo", può sempre modificare una variabile const usando un puntatore:
In questo caso non ci sarebbe alcun warning o errore da parte del compilatore e il programma stampa quindi: a = 20codice:#include <stdio.h> int main (void) { const int a = 10; int *pa; pa = (int*) &a; *pa = 20; printf ("a = %d\n", a); return 0; }
Hai provato se funziona il trucchetto ... ? Compilalo con VC++ ...Originariamente inviato da newbie
Secondo me la faccenda è più sottile e complessa di quanto sembri...
Premettendo che neanch'io sono d'accordo sul fatto che una costante si possa modificare, già il fatto che ciò sia possibile, pur se non corretto, (sia perchè il compilatore scelto lo permetta sia utilizzando trucchetti tipo i puntatori), ...
Sì, è una variabile, ovviamente di tipo "immutable" (o read-only, chiamala come vuoi). Ma è una variabile. Gli viene assegnato uno spazio di n bytes in memoria, ha un suo indirizzo, ecc... Quindi ha le stesse caratteristiche delle altre variabili "normali". Salvo il fatto che si chiede al compilatore di controllare durante la compilazione che non vengano fatte assegnazioni.Originariamente inviato da oregon
No ... sbagli tu a dire che e' "a tutti gli effetti " una variabile.
Guarda a questi link: [1] [2]
Si parla chiaramente di variabili.
Certo!!!!!!Originariamente inviato da oregon
E poi sei sicuro che verrebbe visualizzato 20 ?
Provato con Visual C++.net 2003 e con gcc su una Slackware 9.1
Ma poi mi sembra ovvio. Se io riesco ad ottenere un indirizzo X e questo indirizzo punta ad una zona di memoria scrivibile (ovvero esiste della memoria mappata a quel indirizzo e il processore non opera delle protezioni particolari) allora posso scriverci dentro!!!
E' una questione molto "sottile" ...
Magari i due termini sono ambedue sbagliati perche' e' un "misto" ... e sono d'accordo se la chiamiamo "read only variable". Ma se si deve scegliere tra "variabile" e "costante" devo dire che la prima e' sbagliata.
Tanto che, con un compilatore serio , il trucchetto del puntatore non funziona e la "read only variable" viene gestita come una vera e propria "costante".
A dimostrazione di questo, nel seguente codice
la rigacodice:#include <stdio.h> int main (void) { const int a = 10; int *pa; pa = (int*) &a; *pa = 20; printf ("a = %d\n", a); return 0; }
printf ("a = %d\n", a);
viene trasformata in assembler dal compilatore, in questo modo
proprio per il significato di "costante" che essa assume.codice:00401018 push 0Ah 0040101A push offset string "a = %d\n" (4060FCh) 0040101F call printf (40102Ah)