Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Variabile globale... Help!
Forum - C/C++ - Variabile globale... Help!

Pagine: [ 1 2 ] Precedente | Prossimo
Avatar
xeeynamo (Normal User)
Pro


Messaggi: 66
Iscritto: 14/03/2008

Segnala al moderatore
Postato alle 23:29
Lunedì, 03/05/2010
Ciao a tutti!
Ho 3 file .cpp ed uno di questi contiene il main. Ognuno di questi include un header globale che continene una singola variabile che dovrebb'essere usata da tutti e 3 i file .cpp però al momento della compilazione mi da errore dicendo che quella variabile è stata dichiarata più volte. Allora provo a scrivere prima del tipo della variabile la parola static. Compila però ogni .cpp ha la sua variabile 'vars' che risulterà sempre diversa per  i 3 diversi sorgenti. Sò che a spiegare queste cose non sono molto bravo e gli esempi pratici sono più comprensibili:

Codice sorgente - presumibilmente C/C++

  1. // prova1.cpp
  2. #include "header.h"
  3. void prova1(){ printf("1: %i\n", var);


Codice sorgente - presumibilmente C/C++

  1. // prova2.cpp
  2. #include "header.h"
  3. void prova2(){ printf("2: %i\n", var);


Codice sorgente - presumibilmente C/C++

  1. // main.cpp
  2. #include "header.h"
  3. int main()
  4. {
  5.     printf("Main says %i\n", vars);
  6.     prova1();
  7.     prova2();
  8. }


Codice sorgente - presumibilmente C/C++

  1. // header.h
  2. int vars = 123;



Così mi da errore, invece se faccio static int vars compila ma l'indirizzo della variabile vars risulta diverso per ogni file cpp. Potrei anche fare getVars(); però a creare una funzione per ogni variabile che prende e/o setta è una abbastanza noiosa anche perchè il codice finale sarà abbastanza grande. Ho pensato anche ad assegnare per ogni variabile un indirizzo specifico però all'atto pratico è instabile ed è anche più lenta l'esecuzione del codice. Come fare?

PM Quote
Avatar
HeDo (Founder Member)
Guru^2


Messaggi: 2765
Iscritto: 21/09/2007

Segnala al moderatore
Postato alle 23:58
Lunedì, 03/05/2010
è un errore piuttosto comune, la soluzione però è molto semplice :)

dichiara la variabile globale nel file main.cpp, negli altri file di codice dichiara la stessa variabile (cioè stesso nome e tipo) con l'attributo extern.

esempio:

*** main.cpp ***

Codice sorgente - presumibilmente C/C++

  1. int iShared;
  2.  
  3. int main() {
  4.  
  5.     [...]
  6.  
  7. }



*** altrofile.cpp ***

Codice sorgente - presumibilmente C/C++

  1. extern int iShared;
  2.  
  3. [...]



tutto questo funziona perchè l'attributo extern delega al linker risolvere la locazione effettiva della variabile che la cerca negli altri file di codice oggetto generato dal compilatore.

Ultima modifica effettuata da HeDo il 04/05/2010 alle 0:02
PM Quote
Avatar
Poggi Marco (Member)
Guru


Messaggi: 969
Iscritto: 05/01/2010

Segnala al moderatore
Postato alle 0:01
Martedì, 04/05/2010
Prova a dichiarare la variabile vars  extern. In questo modo sara visibile in tutti i file. Però, a mio avviso, questa pratica è troppo pericolosa.

Come fai ad asegnare "un indirizzo specifico" ad una variabile?

PM Quote
Avatar
HeDo (Founder Member)
Guru^2


Messaggi: 2765
Iscritto: 21/09/2007

Segnala al moderatore
Postato alle 0:04
Martedì, 04/05/2010
Testo quotato

Postato originariamente da Poggi Marco:

Prova a dichiarare la variabile vars  extern. In questo modo sara visibile in tutti i file. Però, a mio avviso, questa pratica è troppo pericolosa.




pratica pericolosa? che fa esplode?

ti riferisci alla possibile sincronizzazione tra accessi concorrenti? non credo sarà un suo problema a breve, data la domanda ;)

Ultima modifica effettuata da HeDo il 04/05/2010 alle 0:04
PM Quote
Avatar
xeeynamo (Normal User)
Pro


Messaggi: 66
Iscritto: 14/03/2008

Segnala al moderatore
Postato alle 0:16
Martedì, 04/05/2010
@HeDo: Il tuo sistema funziona alla grande!!! Ho fatto un altro .cpp con al suo interno tutte le variabili per non ingrandire ancora di più il main.

@Poggi Marco: Per esempio se ho delle variabili che formano in totale 8byte faccio così:
Codice sorgente - presumibilmente C/C++

  1. int main()
  2. {
  3.     void* p = malloc(8);
  4.     byte* a = (byte*)p+0;
  5.     byte* b = (byte*)p+1;
  6.     u16* c = (u16*)p+2;
  7.     u32* d = (u32*)p+4;
  8.     u32* e = (u32*)p+8;
  9.     *c = 0xABCD;
  10.     printf("%X", *c);
  11. }



avevo fatto in modo di generalizzare gli indirizzi nell'header e così potevo gestirmi le variabili lavorando direttamente sulla memoria

PM Quote
Avatar
Poggi Marco (Member)
Guru


Messaggi: 969
Iscritto: 05/01/2010

Segnala al moderatore
Postato alle 0:28
Martedì, 04/05/2010
@ HeDo: Per "pratica pericolosa", intendo dire che è complicata la gestione di una variabile, quando viene utilizzata direttamente da più funzioni.

@ xeeynamo : Ho letto il too metodo di assegnamento della memoria.
Ho un dubbio: così facendo, determini  direttamente tu l' allocazione della variabile?

Ultima modifica effettuata da Poggi Marco il 04/05/2010 alle 0:29
PM Quote
Avatar
HeDo (Founder Member)
Guru^2


Messaggi: 2765
Iscritto: 21/09/2007

Segnala al moderatore
Postato alle 1:00
Martedì, 04/05/2010
Testo quotato

Postato originariamente da xeeynamo:

@HeDo: Il tuo sistema funziona alla grande!!! Ho fatto un altro .cpp con al suo interno tutte le variabili per non ingrandire ancora di più il main.

@Poggi Marco: Per esempio se ho delle variabili che formano in totale 8byte faccio così:
Codice sorgente - presumibilmente C/C++

  1. int main()
  2. {
  3.     void* p = malloc(8);
  4.     byte* a = (byte*)p+0;
  5.     byte* b = (byte*)p+1;
  6.     u16* c = (u16*)p+2;
  7.     u32* d = (u32*)p+4;
  8.     u32* e = (u32*)p+8;
  9.     *c = 0xABCD;
  10.     printf("%X", *c);
  11. }



avevo fatto in modo di generalizzare gli indirizzi nell'header e così potevo gestirmi le variabili lavorando direttamente sulla memoria



asd, sai che hanno inventato le struct per una ragione? :D

cmq la pratica sconsiglia di usare troppe variabili globali, fanne un uso pesato e responsabile.

@Marco: non devi gestire niente, la variabile globale serve ad esempio se hai N (grande) di funzioni che hanno bisogno tutte dello stesso parametro, a quel punto per non avere overhead durante le invocazioni promuovi un parametro a variabile globale. L'esempio che ti ho fatto è molto semplificato, certe "pratiche" di promozione vanno adottate solo dopo un attento studio tramite profiler e solo in applicazioni realtime o time critical. Per il resto la potenza dei processori odierni permette queste e altre "porcate" senza battere ciglio ;)

PM Quote
Avatar
TheKaneB (Member)
Guru^2


Messaggi: 1792
Iscritto: 26/06/2009

Segnala al moderatore
Postato alle 3:21
Martedì, 04/05/2010
quoto HeDo, e aggiungo che l'uso di variabili globali su alcune architetture porta a, diciamo, "curiose" conseguenze.

Faccio un esempio (classico) con il Nintendo DS (processore ARM), con il quale ho avuto modo di sbattere la testa parecchio in passato...

Sul DS lo stack viene posizionato su una memoria speciale (la DTCM) che è direttamente attaccata alla CPU (non passa per il bus di sistema, come fosse una cache L2, ma gestita in manuale), mentre l'heap è posizionato nella Ram di sistema.

La DTCM ha un accesso a 32bit, sincrono con il clock della CPU (se la memoria non mi inganna), e usata in coppia con la ITCM (cache per le istruzioni) permette alla CPU di fetchare istruzioni e operandi contemporaneamente (architettura harvard).
Quando invece si accede alla system ram, si passa attraverso un bus a 16 bit, con la metà del clock (quindi 4 cicli di clock in modalità burst, 6 cicli di clock per fetch "sparsi").

Ecco quindi che, in questo caso, se dichiaro una variabile globale, oppure allocata con malloc (quindi nell'heap), questa risulta mediamente 6 volte più lenta in lettura/scrittura rispetto ad una variabile locale (nello stack, o addirittura su uno dei 13 registri general purpose).

Per ovviare al problema allocavo un piccolo buffer in stack da 1K o poco più, sul quale copiavo una parte dei dati da elaborare (principalmente grafica 2D/3D), e procedevo di volta in volta con il processo "in streaming" passando dalla system ram, alla DTCM, e da qui direttamente alla scheda video....

ah.... belle cose :D trucchetti e diavolerie che su pc fanno ridere, ma quando hai 66MHz di processorino, sono quelli che fanno la differenza tra 15 frame per secondo scarsi e 60fps costanti!

PS: Chiudo l'OT aggiungendo che su PC non esiste la DTCM, e lo stack risiede tutto nella system ram... inoltre la cache del processore è così grossa da rendere inutili interventi "manuali" come quello che ho descritto, quindi prendetela più come una "perla" che come un suggerimento di programmazione :k:

Ultima modifica effettuata da TheKaneB il 04/05/2010 alle 3:22
PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 6402
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 7:37
Martedì, 04/05/2010
Testo quotato

Postato originariamente da xeeynamo:
int main()
{
    void* p = malloc(8);
    byte* a = (byte*)p+0;
    byte* b = (byte*)p+1;
    u16* c = (u16*)p+2;
    u32* d = (u32*)p+4;
    u32* e = (u32*)p+8;
    *c = 0xABCD;
    printf("%X", *c);
}




Cos'è ... ? Un nuovo gioco ? :)

(A parte il fatto che la e sfonda il buffer ... :yup: )

Ultima modifica effettuata da nessuno il 04/05/2010 alle 7:39


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità.
PM Quote
Pagine: [ 1 2 ] Precedente | Prossimo