Pagina 1 di 3 1 2 3 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 21
  1. #1
    Utente di HTML.it L'avatar di XWolverineX
    Registrato dal
    Aug 2005
    residenza
    Prague
    Messaggi
    2,565

    Ossimoro di programmazione

    Guardate un po

    codice:
    const int a = 10;
    Questa è una variabile costante.
    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

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Beh ... veramente sei tu che hai scritto "variabile costante".

    Quella e' solamente una costante.

  3. #3
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Originariamente inviato da oregon
    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.

    Se scrivo:
    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;
    }
    il compilatore ha sicuramente qualcosa da obiettare.
    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
    Comunque se uno volesse "fare il furbo", può sempre modificare una variabile const usando un puntatore:
    codice:
    #include <stdio.h>
    
    int main (void)
    {
        const int a = 10;
        int *pa;
    
        pa = (int*) &a;
    
        *pa = 20;
        printf ("a = %d\n", a);
    
        return 0;
    }
    In questo caso non ci sarebbe alcun warning o errore da parte del compilatore e il programma stampa quindi: a = 20

    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.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Originariamente inviato da andbin
    Sbagliato! È a tutti gli effetti una variabile.
    No ... sbagli tu a dire che e' "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.

    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.
    Esatto. Proprio perche' non e' una variabile e il compilatore lo ricorda al programmatore distratto.

    Originariamente inviato da andbin
    Se scrivo:
    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;
    }
    il compilatore ha sicuramente qualcosa da obiettare.
    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
    Mi sembra che il comportamento di VC++ sia piu' corretto.
    Se l'oggetto e' const, non puo' essere modificato come fosse una variabile.

    Originariamente inviato da andbin

    Comunque se uno volesse "fare il furbo", può sempre modificare una variabile const usando un puntatore:
    codice:
    #include <stdio.h>
    
    int main (void)
    {
        const int a = 10;
        int *pa;
    
        pa = (int*) &a;
    
        *pa = 20;
        printf ("a = %d\n", a);
    
        return 0;
    }
    In questo caso non ci sarebbe alcun warning o errore da parte del compilatore e il programma stampa quindi: a = 20

    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.
    Questa non e' una "furbizia".
    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;

  5. #5
    Utente di HTML.it L'avatar di newbie
    Registrato dal
    Dec 2005
    Messaggi
    299
    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...

  6. #6
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Originariamente inviato da andbin
    Comunque se uno volesse "fare il furbo", può sempre modificare una variabile const usando un puntatore:
    codice:
    #include <stdio.h>
    
    int main (void)
    {
        const int a = 10;
        int *pa;
    
        pa = (int*) &a;
    
        *pa = 20;
        printf ("a = %d\n", a);
    
        return 0;
    }
    In questo caso non ci sarebbe alcun warning o errore da parte del compilatore e il programma stampa quindi: a = 20
    E poi sei sicuro che verrebbe visualizzato 20 ?

  7. #7
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    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), ...
    Hai provato se funziona il trucchetto ... ? Compilalo con VC++ ...

  8. #8
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Originariamente inviato da oregon
    No ... sbagli tu a dire che e' "a tutti gli effetti " una variabile.
    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.

    Guarda a questi link: [1] [2]

    Si parla chiaramente di variabili.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  9. #9
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Originariamente inviato da oregon
    E poi sei sicuro che verrebbe visualizzato 20 ?
    Certo!!!!!!
    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!!!
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  10. #10
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    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

    codice:
    #include <stdio.h>
    
    int main (void)
    {
        const int a = 10;
        int *pa;
    
        pa = (int*) &a;
    
        *pa = 20;
        printf ("a = %d\n", a);
    
        return 0;
    }
    la riga

    printf ("a = %d\n", a);

    viene trasformata in assembler dal compilatore, in questo modo

    codice:
    00401018 push        0Ah  
    0040101A push        offset string "a = %d\n" (4060FCh) 
    0040101F call        printf (40102Ah)
    proprio per il significato di "costante" che essa assume.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.