Newsgroup: it.comp.lang.c++
Titolo: eccezioni e variabili globali

Come faccio a catturare le eccezioni sollevate dall'inizializzazione 
delle variabili globali?
ad esempio:
class T {
   public:
   T() {
     throw runtime_error("test");
   };
};
T x;
main() {
   // non viene eseguito!
}
E.

?manu* ha scritto:

So che gli oggetti e le variabili statiche vengono costruite PRIMA
dell'ingresso dentro main(), per cui se c'è un errore nel loro
costruttore il programma termina in malo modo, prima ancora di cominciare.
Forse anche oggetti e variabili globali adottano un meccanismo simile,
per cui il costruttore solleva l'eccezione ma il "catcher" ancora non
esiste, e l'eccezione non viene gestita affatto... ?

 handlers specifici (come _atexit) o _unexpected o roba di nome e senso 
Penso di poter mettere degli handler che venogno eseguiti prima delle 
inizializzazioni e dopo le de-inizializzazioni. Solo che non posso 
mettere il try in uno e il catch nell'altro... dovrei ridefinire la 
funzione che chiama main.
E.

 delle variabili globali?
Non ne sono del tutto certo ma temo non sia possibile visto che le
varibili globali vengono create prima della chiamata a main.
Comunque le variabili globali non sono molto belle, io non le uso mai.
Una possibilita' sarebbe usare una classe singleton che nel
costruttore crea dinamicamente la tua variabile globale e fa il catch
dell'eccezione.
Saluti,
The Librarian

 delle variabili globali?
Non e' possibile. Un'altra indicazione del fatto che e' meglio non
abusare delle variabili globali.
Ciao,
Nicola

 abusare delle variabili globali.
Grazie! Speravo si potesse fare... Devo per forza utilizzare una 
variabile globale, perché viene utilizzata in uno hook a cui non posso 
aggiungere parametri.
Ora sto pensando a queste due alternative:
class T {
   public:
   T() throw; // non lancia eccezioni
   void init() throw runtime_error;
};
T x;
main() {
   try {
     x.init();
   } catch (runtime_error &e) {
   // [...]
   }
}
oppure
class T {
   public:
   T() throw runtime_error;
};
T *x=0;
main () {
   try {
     x= new T;
   } catch(runtime_error &e) {
   // [...]
   }
}
Il problema è che l'oggetto T nell'inizializzazione legge i propri dati 
da un file, e lancia un'eccezione se il file non c'é o non è corretto. 
Immagino che la prima soluzione sia più "giusta" se ha senso avere un 
oggetto T con una inizializzazione di default che non abbisogna di 
leggere i dati dal file. In caso contrario (se non ha senso avere un 
oggetto T "vuoto") immagino sia più corretta la seconda (che però mi 
costringe a modificare tutti gli x. in x->
E.
E.
E.

 costringe a modificare tutti gli x. in x->
Viste le premesse, e' proprio necessario lanciare l'eccezione? Non ti
conviene usare semplicemente qualche if su dei codici di errore?
Ciao,
Nicola

 conviene usare semplicemente qualche if su dei codici di errore?
Trovo molto comodo l'utilizzo delle eccezioni, soprattutto quando si ha 
a che fare con il parsing di file dati. Nel punto in cui trovo un errore 
nell'input non è detto che sia in grado di indicare il nome del file e 
il numero di riga. Genero un'eccezione che viene intercettata una volta 
per aggiungere alla descrizione dell'errore il numero di riga e una 
seconda volta per aggiungere il nome del file! Mi sembra un utilizzo 
molto appropriato.
In realtà mi sono reso conto che devo utilizzare un puntatore globale. 
Infatti per ora ho una unica istanza della variabile T, ma in 
prospettiva tale istanza potrebbe cambiare in runtime.
E.

 aggiungere parametri.
Beh, magari riesci a risolvere banalmente facendo:
T *x;
int main() {
        try {
                x = new T;
        } catch (...)
                ...
        }
        ...
        delete x;
}
no?
Luca
-- 
Dicono che  il cane sia  il miglior  amico dell'uomo. Secondo me  non e`
vero. Quanti dei vostri amici avete fatto castrare, recentemente?

 molto appropriato.
Si, se la stuazione non e' recuperabile. Se invece lo e' no.
Ciao,
Nicola

 delle eccezioni tende a rendere il codice contorto.
No, io in realtà farei comunque terminare il programma, e quindi il 
problema non si porrebbe. Era solo per capire il senso di quel 
comportamento.
E.

 specifica che comportamento va adottato in questa situazione?
No, no, non ho controllato, ma secondo me lo standard specifica
proprio questo comportamento. Il problema piuttosto e': quanti lo
sanno / se lo aspettano? La tendenza all'animismo (= le cose si
aggiustano da sole per miracolo) e' gia' forte nel mondo dello
sviluppo software italiano e forse non solo, e non mi pare il caso di
gettare benzina sul fuoco.
Ciao,
Nicola

 aggiungere parametri.
Non so esattamente cosa stai facendo e forse dico na fesseria, ma se
l'hook lo scrivi tu, non potresti creare un terzo oggetto che tiene
memoria di un valore passatogli e lo restituisce se interrogato?
Un oggetto "repository" con due soli metodi:
void *Get(string Nomevar);
bool Set (string Nomevar, string Value);
che in pratica funzionerebbe come un array PHP... e potresti fregartene
delle variabili globali.