Newsgroup: it.comp.lang.c++
Titolo: Variabili all'interno del CASE

Salve a tutti! Mentre mi accingevo a programmare ho notato un particolare
strano: e' normale che il compilatore mi segnali errori di inizializzazione
di variabili all'interno di un CASE? Il codice e' qui sotto riproposto:
[NOTA: nonostante riguardi la gestione di messaggi Window, ho postato qui la
domanda perche' suppongo inerente al C++ e non alle API Win32 - smentitemi
se sbaglio]
----------------------------------------------------------------------------
-----------------------------------
case WM_LBUTTONDOWN:
    char szFileName[MAX_PATH];
    HINSTANCE hinstance = GetModuleHandle(NULL);        [*]
    GetModuleFileName(hinstance, szFileName, MAX_PATH);
    MessageBox(NULL, szFileName, "Il nome del file e':",
MB_OK|MB_ICONINFORMATION);
    break;
----------------------------------------------------------------------------
-----------------------------------
Il problema l'ho presto risolto subito modificando la riga con [*] (e'
piuttosto banale) tuttavia vorrei capire se questo comportamento e' normale
o meno. Grazie in anticipo
HellHound - uccidi CERBERO per l'email

si, MSVC6 da questo tipo di warning anche se altri compilatori non lo danno

 si, MSVC6 da questo tipo di warning anche se altri compilatori non lo danno
Warning? Gli altri compilatori danno un bell'errore. Per aggirarlo
metti il contenuto del tuo case tra graffe.
Ciao,
Nicola

 si, MSVC6 da questo tipo di warning
No, da proprio errore... 
-- 
Luc.

 di variabili all'interno di un CASE? 
Direi di sì.
Il problema è facilmente comprensibile se si considera che
i case possono essere considerate alla stregua di etichette
che marcano vari punti del codice di un (e un solo) blocco.
Se definisci (ed eventualmente, e ragionevolmente, inizializzi)
una variabile in un case, quella variabile potrebbe essere a tutti
gli effetti utilizzata anche nei case sottostanti (perché
l'esecuzione è a cascata fino al termine del blocco o al primo break),
ma
(1) mentre non dovrebbe essere definita nuovamente (lo sarebbe più volte,
siamo sempre nel medesimo blocco)
(2) si potrebbe del resto saltare direttamente in uno dei case
inferiori che la utilizzano senza averla mai definita.
E' per evitare questa contraddizione che non è consentita la inizializzazione
di variabili entro i case.
Un possibile escamotage è quello di racchiudere il codice 'controllato'
dal case in un blocco (cioè entro parentesi graffe), ma vale nel solo caso
di una variabile utile localmente: non sarebbe infatti referenziabile
all'esterno del blocco (è distrutta all'uscita).
Oppure la definisci esternamente allo switch.
Ciao.

Il principio mi sembra corretto ma non del tutto coerente in un 
compilatore MSVC6.
int main(int argc, char* argv[])
{
	printf("Hello World!\n");
	switch( argc ) {
	case 1:
		int var1 = 1;   // genera errore su case2 e default
				// ma non viene utilizzata
		break;
	case 2:
		printf("argc=2\n");
		break;
	default:
		printf("argc>2\n");
	}
 
	if( argc == 2 )
		int var2 = 2;	// non genera errore se non viene
				// utilizzata
 
	goto myLabel;
	int var3 = 3;		// genera errore su myLabel anche se non 				// viene usata.
 
	return 0;
myLabel:
	printf( "Fine!\n" );
	return 1;
}
Secondo me dovrebbe dare errore anche su var2.
Cosa ne pensate?
  -Ema-

var2 non da errore xche' e' definita all'interno di un blocco if per cui lo 
scope di var2 inizia con l'if e con esso finisce
Sarebbe come scrivere
if (..)
{
int var2 = 2
}

Cosa ne pensate?
Quella definizione di variabile e' come se fosse in una
coppia di parentesi graffe... in particolare smette di
esistere dopo quella istruzione.
In C++ quello che e' vietato e' saltare in un punto in cui
esiste una variabile senza passare per il punto in cui la
variabile viene definita. Nel caso di var2 l'intera parte
in cui la variabile esiste viene "scavalcata", e questo
non e' ovviamente un problema.
HTH
Andrea

 esistere dopo quella istruzione.
La mia risposta vale anche per Giallanon.
Non ho fatto una prova ma da quello che dite immagino che anche gli 
altri compilatori si comportino allo stesso modo.
Quello che non mi piace e' che in questo caso venga applicato il 
concetto di blocco di codice. Ciò che io metto nell'if non è un blocco 
di codice ma un'istruzione. Evidentemente viene considerato un blocco di 
codice ma trovo che sia poco chiaro non essendoci nessuna graffa a 
delimitarlo. Nel caso del for la dichiarazione di una variabile 
nell'istruzione di inizializzazione appartine al blocco in cui è 
contenuto il for e non solo del blocco eseguito dal for.
Non contesto il fatto che i compilatori si comportino come dite voi 
(vorrei andare a vedere l'esatta definizione del linguaggio), contesto 
la mancanza di uniformità e di chiarezza nella sintassi.
Ciao.
  -Ema-

 contenuto il for e non solo del blocco eseguito dal for.
No:
for (int i = 0; i < 5; i++) {
        /* Qui la variabile i e` visibile */
}
/* Qui` i non esiste piu` */
VC++5 estendeva erroneamente la vita della variabile i. Non so se questo
sia stato corretto nelle versioni piu` recenti.
Kronos
-- 
Home: 
http://kronoz.cjb.net
Una donna sposa un uomo sperando che cambi, e lui non cambiera`. Un
uomo sposa una donna sperando che non cambi, e lei cambiera`.

la mancanza di uniformitą e di chiarezza nella sintassi.
Se cerchi un linguaggio uniforme e con una sintassi
chiara mi spiace ma devo dirti con il C++ sei capitato
abbastanza male ...
HTH
Andrea

 
Uso diversi linguaggi ma il C/C++ e' quello che uso da piu' tempo. Dai 
drivers alle applicazioni con UI a server di rete. Solitamente e' quello 
con cui mi diverto di piu'. Forse ha una sintassi un po' ostica ma, come 
in tutti i linguaggi, dipende dal programmatore scrivere un codice 
leggibile.
Grazie comunque per le informazioni.
-Ema-

 sia stato corretto nelle versioni piu` recenti.
  Si', ma credo che non sia stato un passaggio tanto indolore: c'erano
tonnellate di codice che sfruttavano questa "caratteristica", tant'e' vero
che quando mi dissero che era sbagliato non ci ho creduto finche' non l'ho
letto sullo Stroustrup :)
_dave_

 
e beh ma questo e' un "errore" di MSVC6 xche' in teoria la variabile 
dichiarata nell'inizializzazione del for dovrebbe esistere solo per la 
durate del ciclo for:
for (int i=0;i<10;i++)
    	DoSomething (i)
--> QUI i non dovrebbe piu' esistere