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?!
- 1733 megtekintés
Hozzászólások
probald meg igy: http://my-cat-is-a.dyn-o-saur.com/hosted/switch.c
---------------------
Ригидус а бетегадьбол
- A hozzászóláshoz be kell jelentkezni
nem illik ilyen keson deklaralni. fordits -pedantic -ansi -Wall -lal, es sok hibat kiszursz.
- A hozzászóláshoz be kell jelentkezni
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...
- A hozzászóláshoz be kell jelentkezni
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
---------------------
Ригидус а бетегадьбол
- A hozzászóláshoz be kell jelentkezni
#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?
- A hozzászóláshoz be kell jelentkezni
Szerintem az ott volt, csak a drupal - szokas szerint - kigyomlalta, ha nem "" koze teszi. Maskepp html tag-nek erzekeli. :-)
---------------------
Ригидус а бетегадьбол
- A hozzászóláshoz be kell jelentkezni
Mar leesett,de azert koszi
- A hozzászóláshoz be kell jelentkezni
off: bug a C/gcc hasznalojaban? :)
- A hozzászóláshoz be kell jelentkezni
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.
- A hozzászóláshoz be kell jelentkezni
nem bugzik az, elfelejtette {} jelek koze tenni az int i; es printf();-et. :-)
---------------------
Ригидус а бетегадьбол
- A hozzászóláshoz be kell jelentkezni
Legyszi, keresd meg! Engem nagyon erdekelne!
Zsiraf
- A hozzászóláshoz be kell jelentkezni
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...
- A hozzászóláshoz be kell jelentkezni
Nem voltal tudataban annak, hogy a case XXX: egy label
Na ennek én sem. Pedig így utólag logikus.
Ezért már megérte elolvasnom ezt a topikot.
- A hozzászóláshoz be kell jelentkezni
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...
- A hozzászóláshoz be kell jelentkezni
$ magyar -o hozzaszolas hozzaszolas.magyar
hozzaszolas.magyar: In function 'body':
hozzaszolas.magyar:2: error: syntax error, 'ly' missing between 'o' and 'an'
- A hozzászóláshoz be kell jelentkezni
ROTFL
---------------------
Ригидус а бетегадьбол
- A hozzászóláshoz be kell jelentkezni
így legalább nem kell gondolkodnom, hogy ly-nal vagy j-vel írják az olyan-t :D:D:D:D
- A hozzászóláshoz be kell jelentkezni
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
- A hozzászóláshoz be kell jelentkezni
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.
- A hozzászóláshoz be kell jelentkezni
Hmm... :-)
Ajanlom:
gcc test.c -std=c89 -pedantic-errors
test.c: In function 'main':
test.c:6: error: ISO C90 forbids mixed declarations and code
Zsiraf
p.s.: ja a test.c-ben egy olyan mixed deklaracio volt, nem csokolade :-) ... no pa, indulok haza
- A hozzászóláshoz be kell jelentkezni
ez igaz... aki portabilis kódot ír, az használjon -pedantic-errors-ot és probléma megoldva... csak hát ezzel kellett volna kezdeni az egészet :)
p.s. még jó hogy nem csoki... tegnap ettem 1 csokit, arra is ráfért volna 1 pedantic-errors :D:D
- A hozzászóláshoz be kell jelentkezni
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...
- A hozzászóláshoz be kell jelentkezni
erről beszéltem :)
- A hozzászóláshoz be kell jelentkezni