C/gcc bug a switch-ben?!

Fórumok

Sziasztok!

A minap egy switch-t tartalmazó függvényt szintaktikai hiba miatt nem tudtam lefordítani a gcc-vel. Nem értettem mi a probléma, utánajártam, próbálgattam, és amit tapasztaltam, nem hittem el.(még most sem..)
A próba kód a következő:
#include
int main()
{
int k = A;
switch (k)
{
case 0 :
/*int i;*/
printf("A\n");
break;
case 1 :
printf("B\n");
break;
case 2 :
printf("C\n");
break;
}
return 0;
}

Ez a kód minden további nélkül lefordul, és helyesen működik. Azonban ha kiveszitek a kommentből az int i; -t szintaktikai hibát fogtok kapni(legalábbis remélem.)
Nálam ezt:

$ gcc -o proba switch_bug.c
switch_bug.c: In function 'main':
switch_bug.c:10: error: syntax error before 'int'

gcc version 4.0.2 20050808 (prerelease) (Ubuntu 4.0.1-4ubuntu9)

Ha az int i; elé teszek egy printf-t, if-t, függvényhívást, bármit, akkor lefordul. A tapasztalataim alapján akkor nem fordul le, ha a case akarmi : után jön egyből ez a deklaráció. (unsigned long int-re, char-ra, mindenre ez van.)

Most én vagyok a nagyon lamer, és nem tudtam ezt a szintaktikai ficsőrt, vagy ez tényleg valami hiba?!

Hozzászólások

nem illik ilyen keson deklaralni. fordits -pedantic -ansi -Wall -lal, es sok hibat kiszursz.

Hmm... az info gcc a kovetkezot mondja:


5.23 Mixed Declarations and Code
================================

ISO C99 and ISO C++ allow declarations and code to be freely mixed
within compound statements.  As an extension, GCC also allows this in
C89 mode.  For example, you could do:

     int i;
     /* ... */
     i++;
     int j = i + 2;

 Each identifier is visible from where it is declared until the end of
the enclosing block.

Tehat ebben nincs hiba. A problema, valoszinuleg ott van, hogy a case xxx: tulajdonkeppen egy label. Es, mint label, termeszetesen egy utasitasra kell mutatnia ( cimke: utasitas...). viszont a valtozo deklaracio nem utasitas, azt nem lehet megcimkezni!!! Csak utasitast tudsz megcimkezni. Igy a case xxx: utan ertelemszeruen nem allhat valtozo deklaracio! Hiszen arra nem lehet vezerlest atadni...

Zsiraf

p.s.: ha egy "ures utasitast" raksz (;) az mar megteszi, de
szerintem semmi ertelme, vidd ki a deklaraciot a swictch utan...

ja ize, latom mar: te a case-n belul nem hoztal letre uj block-ot. A printf-fel egyutt ok mar ketten lesznek egy agban.

szerk: kijavitottam a fajlt a fenti linken
---------------------
Ригидус а бетегадьбол

#include

Ezzel mit akartal? Valami nem hianyzik innen?
int k = A;

nekem erre ez jott:

In function `main':
error: `A' undeclared (first use in this function)
error: (Each undeclared identifier is reported only once
error: for each function it appears in.)

hmm...
Nekem gcc 3.4.4 van. Lehet hogy a 4-esben mar megengedett.

Azonban ha kiveszitek a kommentből az int i; -t szintaktikai hibát fogtok kapni(legalábbis remélem.)

nekem amugy is.
case 0

nem igy kene: case '0'?

Az int i -vel mit akartal,ha nem hasznalod fel?

http://nsuperbus.blogspot.com

Kétlem, hogy a gcc lenne a ludas, de ha még kérdéses, hogy miért csinálja, akkor a gcc forráskódjában szívesen megkeresem, hogy hol és miért találja hibásnak.
Ha tényleg úgy gondolod, hogy bugzik a gcc, akkor próbáld ki a 4.1-essel is.

Csak hogy meg tisztabban lassunk (meg elneztem a sok ertelmes hozzaszolast...), szoval ide idezem a lebel-ekrol szolo reszt a C szabvanybol:

  6.8.1 Labeled statements
  Syntax
1        labeled-statement:
                 identifier : statement
                 case constant-expression : statement
                 default : statement
  Constraints
2 A case or default label shall appear only in a switch statement.
  Further constraints on such labels are discussed under the switch
  statement.

Tehat most mar egyertelmuen a label mint olyan nem letezik onmagaban, csak labeled statement van. Viszont nincs labeled variable declaration ;-) Tehat amit irtal a szintaktikailag hibas, amire a gcc fel is hivta a figyelmedet.
Most én vagyok a nagyon lamer, és nem tudtam ezt a szintaktikai ficsőrt, vagy ez tényleg valami hiba?! Igen lamer vagy, de amugy ez nem szintaktikai ficsor, csak rosszul ertelmezted a case XXX:-t. Nem voltal tudataban annak, hogy a case XXX: egy label, es talan azt is elfelejtetted, hogy csak utasitast lehet label-el ellatni.

Zsiraf

p.s.: amugy nyugodtan hidd el amit latsz...

még hozzáfűzném ehhez az elmélyült és szofisztikált C-eszmefuttatáshoz, hogy változók deklarálása ugye blokk elején történő dolog... annak ellenére, hogy a gcc van oan ügyes, hogy elfogadja statement után is... (nálam a 3.3.6-os gcc még -pedantic-kal is csak warningot ad :O).

Szóval... startból nem jó dolog labelled declaration-t csinálni... de ha még beteszel elé egy statement-et is...

p.s. ezek azok a dolgok, amiket szvsz nem kellene megengedni a gcc-ben...

változók deklarálása ugye blokk elején történő dolog...

Egeszen a C89-ig, onnantol fogva lehet keverni az utasitasokkal...

p.s. ezek azok a dolgok, amiket szvsz nem kellene megengedni a gcc-ben...

Nem a gcc-ben "vannak megengedve" hanem a C9X standardban. Tehat ott kene ezzel az otleteddel kopogtatni ;-)

Zsiraf

nah... szóval... idézek a gcc 3.3.6 manualból:
"ISO C99 and ISO C++ allow declarations and code to be freely mixed within compound statements. As an extension, GCC also allows this in C89 mode. "

Ha jól értem akkor a 3.3-as gcc megengedi C89 módban is, hogy keverd őket, amúgy ki van próbálva. Mukk nélkül lefordította a kódomat.
Persze 3.2-es és korábbi verziókkal már nem tudod lefordítani.

Na. Akkor ugye én, mint jó munkásember kérdezem hogy kinek jó ez? Mert aki portabilis kódot akar írni, annak biztos nem. Főleg ha nem-gccvel kell majd fordítani a kódot... Pl. visual c nem engedte meg (13.10.3077).

Tehát ismétlem: ezek azok a dolgok, amiket szvsz nem kellene megengedni a gcc-ben... Csak ha megadod expliciten hogy -std=c99.

Szerény tapasztalataim szerint az ilyen 'szintaktikai engedmények' mint a deklarációk engedélyezése az utasítások között, főleg arra jók hogy könnyebben hozhassunk létre hordozhatatlan programot...