Pagina 2 di 3 primaprima 1 2 3 ultimoultimo
Visualizzazione dei risultati da 11 a 20 su 21
  1. #11
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,481
    Originariamente inviato da andbin
    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!!!
    No ... quello che t'ho scritto vale per VC2003 ... mi sa che non l'hai provato con questo compilatore ...

    Non e' il processore che opera protezioni sulla memoria su cui si deve scrivere... e' semplicemente il compilatore che, come vedi, considera il valore iniziale della costante e non il contenuto della memoria in cui tale valore e' stato inserito.

  2. #12
    Utente di HTML.it
    Registrato dal
    Feb 2003
    Messaggi
    1,965
    E' un bug linguistico, non ti cruciare.

  3. #13
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da oregon
    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".
    Allora ... il fatto che il codice che ho postato possa funzionare o meno, dipende (credo eh, non possiedo tutti i compilatori di questo mondo!) dal compilatore e molto più in particolare specialmente dal modo di compilazione debug o release.

    Il trucchetto funziona:
    -- Con gcc compilandolo in modalità debug (-g)
    -- Con VC++.net 2003 compilandolo in modalità "Debug"
    -- Con VC++.net 2003 compilandolo in modalità "Release"

    Il trucchetto non funziona:
    -- Con gcc compilandolo senza debug e con le ottimizzazioni (-O3)

    In quest'ultimo caso, in effetti, il codice assembly visualizzato con gdb è il seguente:
    codice:
    0x8048340 <main>:       push   %ebp
    0x8048341 <main+1>:     mov    %esp,%ebp
    0x8048343 <main+3>:     sub    $0x8,%esp
    0x8048346 <main+6>:     and    $0xfffffff0,%esp
    0x8048349 <main+9>:     sub    $0x8,%esp
    0x804834c <main+12>:    push   $0xa
    0x804834e <main+14>:    push   $0x8048424
    0x8048353 <main+19>:    call   0x8048268 <printf>
    0x8048358 <main+24>:    mov    %ebp,%esp
    0x804835a <main+26>:    xor    %eax,%eax
    0x804835c <main+28>:    pop    %ebp
    0x804835d <main+29>:    ret
    Si vede bene che viene usata la push con un valore immediato di 10.

    Con il VC++.net 2003 il compilatore invece usa sempre una variabile vera e propria. E con mia sorpresa anche in modalità "Release"!!!
    Adesso però non stiamo a fare futili disquisizioni su quale compilatore è il migliore o il più bello, primo perché non ne ho voglia e secondo perché non sono la persona più adatta a giudicare i vari compilatori.

    Comunque su una cosa posso darti ragione (e non ho problemi a riconoscerlo): il "trucchetto" che ho postato può essere tranquillamente vanificato dal compilatore, nel caso in cui il valore venga visto realmente come una costante e non come una variabile read-only. Quindi, appunto, una cosa da non fare.

    Originariamente inviato da oregon
    No ... quello che t'ho scritto vale per VC2003 ... mi sa che non l'hai provato con questo compilatore ...
    Ma se ti ho appena detto che ho fatto le prove con il VC++.net 2003. Ma mi stai prendendo in giro????? Credi che io sia scemo???
    E comunque, come ho appena detto, il VC++ consente il trucchetto sia in modalità Debug che Release, quindi non ho la più pallida idea su dove hai trovato/preso quel pezzo di codice assembly.

    Originariamente inviato da oregon
    Non e' il processore che opera protezioni sulla memoria su cui si deve scrivere... e' semplicemente il compilatore che, come vedi, considera il valore iniziale della costante e non il contenuto della memoria in cui tale valore e' stato inserito.
    Uhm ... ma allora non mi ascolti ...
    Stavo parlando in generale!!!!! Molto in generale ... e non riguardo a questa specifica questione del const.

    Credo che con questo mio post, chiudo la discussione da parte mia, perché mi hai già fatto incavolare abbastanza. E dire che nei forum ai quali sono iscritto ho sempre aiutato un sacco di gente!! ... ma essere preso x scemo questo no.
    Andrea, Senior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  4. #14
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,481
    Intanto faresti bene a calmarti, sia perche' nessuno ti ha preso per "scemo", sia perche' del fatto che ti "incavoli" non mi importa veramente nulla.

    Detto questo, quel "pezzo di codice assembler" non l'ho trovato (ma non dico che mi prendi in giro ...) ma lo ha generato il compilatore (VC2003, v. 7.1.3088, progetto Win32 Console, modalità Release, senza ottimizzazioni, switch /Od). Per la precisione, tutto il main e' il seguente

    codice:
    _main	PROC NEAR
    
    ; 8    : {
    
      00000	55		 push	 ebp
      00001	8b ec		 mov	 ebp, esp
      00003	83 ec 08	 sub	 esp, 8
    
    ; 9    :     const int a = 10;
    
      00006	c7 45 fc 0a 00
    	00 00		 mov	 DWORD PTR _a$[ebp], 10	; 0000000aH
    
    ; 10   :     int *pa;
    ; 11   : 
    ; 12   :     printf ("a = %d\n", a);
    
      0000d	6a 0a		 push	 10			; 0000000aH   
      0000f	68 00 00 00 00	 push	 OFFSET FLAT:$SG9623
      00014	e8 00 00 00 00	 call	 _printf
      00019	83 c4 08	 add	 esp, 8
    
    ; 13   : 
    ; 14   : 	pa = (int*) &a;
    
      0001c	8d 45 fc	 lea	 eax, DWORD PTR _a$[ebp]
      0001f	89 45 f8	 mov	 DWORD PTR _pa$[ebp], eax
    
    ; 15   : 
    ; 16   :     *pa = 20;
    
      00022	8b 4d f8	 mov	 ecx, DWORD PTR _pa$[ebp]
      00025	c7 01 14 00 00
    	00		 mov	 DWORD PTR [ecx], 20	; 00000014H
    
    ; 17   :     printf ("a = %d\n", a);
    
      0002b	6a 0a		 push	 10			; 0000000aH   
      0002d	68 00 00 00 00	 push	 OFFSET FLAT:$SG9625
      00032	e8 00 00 00 00	 call	 _printf
      00037	83 c4 08	 add	 esp, 8
    
    ; 18   : 
    ; 19   :     return 0;
    
      0003a	33 c0		 xor	 eax, eax
    
    ; 20   : }
    
      0003c	8b e5		 mov	 esp, ebp
      0003e	5d		 pop	 ebp
      0003f	c3		 ret	 0
    _main	ENDP
    Dato che a me interessa fare dei confronti tra compilatori, sarebbe interessante capire con quale versione di VC2003 stai operando tu e quale codice assembler viene generato nel caso in cui il "trucco" funzioni ...

    Ma tutto questo "civilmente", altrimenti, non interessa neanche a me.

  5. #15
    Utente di HTML.it L'avatar di XWolverineX
    Registrato dal
    Aug 2005
    residenza
    Prague
    Messaggi
    2,563
    Originariamente inviato da keratox
    E' un bug linguistico, non ti cruciare.
    Infatti.
    Comunque una variabile const è possibile modificarla anche con il cast del C++ const_cast

    codice:
    const int a = 10;
    const_cast<int> a--;
    cout << a;
    sarà uguale a 9
    "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

  6. #16
    Utente di HTML.it L'avatar di XWolverineX
    Registrato dal
    Aug 2005
    residenza
    Prague
    Messaggi
    2,563
    Ad ogni modo io sono piu' daccordo con il ragionamento di andbin, cio è nel fatto che la costante è comunque una variabile.

    Una variabile particolare, in quanto se non fosse una variabile, come afferma oregon, non dovrebbe nemmeno richiedere quantità di memoria per l'allocazione ( cio è un define )
    "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

  7. #17
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,481
    Originariamente inviato da XWolverineX
    Infatti.
    Comunque una variabile const è possibile modificarla anche con il cast del C++ const_cast

    codice:
    const int a = 10;
    const_cast<int> a--;
    cout << a;
    sarà uguale a 9
    Scusa .. non e' per insistere ma quello che hai scritto non e' compilabile. Almeno con VC2003 ... con quale compilatore l'hai compilato e provato?

  8. #18
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,481
    Originariamente inviato da XWolverineX
    Ad ogni modo io sono piu' daccordo con il ragionamento di andbin, cio è nel fatto che la costante è comunque una variabile.

    Una variabile particolare, in quanto se non fosse una variabile, come afferma oregon, non dovrebbe nemmeno richiedere quantità di memoria per l'allocazione ( cio è un define )
    Ognuno e' libero di pensarla come vuole.

    Ovviamente io no.

    Ripeto, la chiamiamo "read only variable" ma nel codice compilato si presenta a tutti gli effetti come una costante e non viene sempre considerato l'indirizzo della sua posizione in memoria.

    In alcuni casi e con alcuni compilatori, e' possibile "variarne" il valore ma sono effettivamente "trucchi" e quindi dovremmo chiamarla "variabile col trucco" ...
    A parte gli scherzi, la miglior definizione e' proprio quella di "bug linguistico" ...

  9. #19
    Utente di HTML.it L'avatar di XWolverineX
    Registrato dal
    Aug 2005
    residenza
    Prague
    Messaggi
    2,563
    Originariamente inviato da oregon
    Scusa .. non e' per insistere ma quello che hai scritto non e' compilabile. Almeno con VC2003 ... con quale compilatore l'hai compilato e provato?
    Dunque hai ragione purtroppo non funziona (eppure ne ero certo).
    Praticamente const cast serve per eludere l'attributo const o volatile del suo operando.
    Una cosa del genere
    codice:
    #include <iostream>
    using namespace std;
    
    class ConstCastTest
    {
    	public:
    		void setNumber(int N) {number = N;}
    		int getNumber() const {return number;}
    		void printNumber() const {	cout <<"Modifico il numero" <<endl;
    									const_cast<ConstCastTest *>(this)->number--;
    									cout <<number;
    								 }
    	private:
    		int number;
    };
    int main()
    {
    	ConstCastTest x;
    	x.setNumber(8);
    	cout <<"Valore iniziale del numero " << x.getNumber() << endl;
    	x.printNumber();
    	getchar();
    }
    Altrimenti è possibile usare l'attributo mutable per specificare che una variabile non deve essere const nemmeno se il suo contesto è const.

    codice:
    class MutableTest
    {
    	public:
             mutable int a;
    };
    int main()
    {
    const MutableTest Testing;
    Testing.a = 10;
    }
    In questo caso il tutto sarà permesso.
    "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

  10. #20
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,481
    Originariamente inviato da XWolverineX
    Dunque hai ragione purtroppo non funziona (eppure ne ero certo).
    Ecco vedi ... non l'avevi provato ...

    Originariamente inviato da XWolverineX
    Praticamente const cast serve per eludere l'attributo const o volatile del suo operando.
    ...

    Altrimenti è possibile usare l'attributo mutable per specificare che una variabile non deve essere const nemmeno se il suo contesto è const.
    ...
    In questo caso il tutto sarà permesso.
    In questi casi non e' il membro che e' costante (non hai mai specificato const per la variabile).

    mutable e' usato proprio per indicare i membri modificabili anche da un metodo const.
    E' un'altra storia.

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 © 2026 vBulletin Solutions, Inc. All rights reserved.