[C]switch, case beginnen met int levert error op

Pagina: 1
Acties:

  • mmedia
  • Registratie: Januari 2002
  • Laatst online: 17-12-2021
Ik heb de volgende code
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void veranderIets (int i){

    switch (i){
    
        case 1:
            /*UNCOMMENT deze printf en het werkt wel*/ /*printf("hallo\n");*/
            int k1;
            k1 = 9;
            break;      
        case 2:
            /*UNCOMMENT deze printf en het werkt wel*/ /*printf("hallo\n");*/
            int k2;
            k2 = 3;
            break;
        default:
            /*UNCOMMENT deze printf en het werkt wel*/ /*printf("hallo\n");*/
            int k3;
            k3 = 2;     
    }
}


Als ik de printf als comment laat staan dan geeft de compiler een parse error before elke int declaratie. Zet ik de printf in de code erbij, dan gaat het wel goed :?

Mag je een case niet beginnen met een int declaratie/initialisatie?

[ Voor 5% gewijzigd door mmedia op 29-03-2004 11:43 ]


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Sommige c-compilers vinden idd dat je de declaraties aan het begin van de scope moet plaatsen, gcc is daar een van.

  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
ACM schreef op 29 maart 2004 @ 11:52:
Sommige c-compilers vinden idd dat je de declaraties aan het begin van de scope moet plaatsen, gcc is daar een van.
Volgens mij heeft dat er weinig mee te maken. Ik haalde het net door comeau en die gaf een "A declaration cannot have a label"-error en idd 'het lost op' met het toevoegen van de printf.

Ik ga even zoeken hoor ;)

  • schoene
  • Registratie: Maart 2003
  • Laatst online: 26-05 21:51
je definieert een int k1, maar kan die in theorie nog gebruiken in case 2,
omdat dit nog dezelfde scope is.
vb:

C++:
1
2
3
4
5
6
7
8
9
    switch (i){
    
        case 1: 
            int k1;
            k1 = 9;
        case 2: 
            k1 += 3;
            break;
    }


Dit zou natuurlijk problemen geven als i == 2. Daarom moet je k1 buiten de switch definieren.

je kan dit wel oplossen door je scope te definieren in je case
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void veranderIets (int i){

    switch (i){
    
        case 1:  {
            int k1;
            k1 = 9;
            break; 
            }       
        case 2: {
            int k2;
            k2 = 3;
            break;
            }       
        default: {
            int k3;
            k3 = 2;        
            }       
    }
}

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

ACM schreef op 29 maart 2004 @ 11:52:
Sommige c-compilers vinden idd dat je de declaraties aan het begin van de scope moet plaatsen, gcc is daar een van.
Nee alle ANSI-C compliant compilers vinden dat.

Een switch is niets anders dan 1 scope die enkele labels introduceert. Het probleem wat je hebt is bijvoorbeeld met deze code:
C++:
1
2
3
4
5
6
7
8
9
switch(MyInteger)
  {
  case 0:
    int Piet = 5;
    break;
  case 1:
    printf("%d", Piet);
    break;
  }

Theoretisch is dit geldig, omdat Piet op de goede scope bestaat. Maar indien MyInteger 1 is wordt de initializer niet gepasseerd en heb je dus undefined behaviour. Om dit te voorkomen is een declaratie binnen een case verboden.

Dat GCC het declareren blijkbaar *tussen* code-regels toestaat is eigenlijk C++ gedrag en dus een GCC-extensie.

De correcte oplossing is oftewel de declaratie globaal plaatsen:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void veranderIets (int i){
    int k1, k2, k3;
    switch (i){
    
        case 1:
            k1 = 9;
            break;        
        case 2:
            k2 = 3;
            break;
        default:
            k3 = 2;        
    }
}

Dit werkt perfect: de declaratie zelf triggert geen code oid en dit is dus gewoon perfect snel. Of de 2e optie is lokale scopes introduceren:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void veranderIets (int i){
    switch (i){
        case 1:
            {
            int k1;
            k1 = 9;
            break;        
            }
        case 2:
            {
            int k2;
            k2 = 3;
            break;
            }
        default:
            {
            int k3;
            k3 = 2;        
            }
    }
}
Dit zal dezelfde code genereren als de andere aanpak in dit geval, maar kan binnen C++ voordelen hebben met betrekking tot constructors. Beste is om gewoon aan te leren dat je geen troep moet declareren binnen een case :)

Professionele website nodig?


  • schoene
  • Registratie: Maart 2003
  • Laatst online: 26-05 21:51
hoe zeggen ze het dan? Great minds think alike of zoiets :+

Verwijderd

schoene schreef op 29 maart 2004 @ 12:05:
hoe zeggen ze het dan? Great minds think alike of zoiets :+
Hmm ja, en ik zal mijn versie dan maar verder weglaten, lijkt veel teveel op jouw post, ik schaar me achter jullie :D

Verwijderd

curry684 schreef op 29 maart 2004 @ 12:02:
[...]

Nee alle ANSI-C compliant compilers vinden dat.
Alle ANSI C99 compliant compilers vinden dat niet meer, toch?

  • Reptile209
  • Registratie: Juni 2001
  • Laatst online: 12:05

Reptile209

- gers -

curry684 schreef op 29 maart 2004 @ 12:02:
[...]
Dit werkt perfect: de declaratie zelf triggert geen code oid en dit is dus gewoon perfect snel. Of de 2e optie is lokale scopes introduceren:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void veranderIets (int i){
    switch (i){
        case 1:
            {
            int k1;
            k1 = 9;
            break;        
            }
        case 2:
            {
            int k2;
            k2 = 3;
            break;
            }
        default:
            {
            int k3;
            k3 = 2;        
            }
    }
}
Dit zal dezelfde code genereren als de andere aanpak in dit geval, maar kan binnen C++ voordelen hebben met betrekking tot constructors. Beste is om gewoon aan te leren dat je geen troep moet declareren binnen een case :)
Blijft alleen nog het punt dat je (met deze voorbeeldcode) van een beetje een lieve compiler de warning krijgt dat "value of k2 never used" en dat 'ie waarschijnlijk de hele boel wegoptimaliseerd.

Zo scherp als een voetbal!


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Verwijderd schreef op 29 maart 2004 @ 12:13:
[...]

Alle ANSI C99 compliant compilers vinden dat niet meer, toch?
Hum nu maak je me nog aan het twijfelen... kan best zijn dat dat veranderd is om meer bij C++ aan te sluiten. Maakt niets uit voor het verhaal ;)

Professionele website nodig?


  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
curry684 schreef op 29 maart 2004 @ 12:02:
Dat GCC het declareren blijkbaar *tussen* code-regels toestaat is eigenlijk C++ gedrag en dus een GCC-extensie.
Nee, comeau vindt ook dat dat mag. Ik begin ook eerder te vermoeden dat het een C-standaard iets is.
[edit]
hihi, dit venster stond al een beetje lang open :+

[ Voor 9% gewijzigd door Glimi op 29-03-2004 13:03 ]


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Glimi schreef op 29 maart 2004 @ 12:59:
[...]

Nee, comeau vindt ook dat dat mag. Ik begin ook eerder te vermoeden dat het een C-standaard iets is.
Zie post boven je sloompie ;) Zal idd wel in C99 zitten, vind het een beetje vreemd regel alleen dat het niet direct na de case zou mogen maar wel met een regel ertussen: dat fixt het scopeprobleem namelijk helemaal niet als je de variabele vanuit een andere case benadert. Logisch zou zijn om het compleet binnen de case te verbieden tenzij je een lokale scope introduceert...

Professionele website nodig?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 10:24

.oisyn

Moderator Devschuur®

Demotivational Speaker

In C99 mag dat idd gewoon

Het punt is overigens dat een declaration geen label mag hebben: je mag alleen jumpen naar executable code, wat een declaration niet echt is. Waarom dat is weet ik ook niet, in C++ mag het namelijk wel

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1