PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : switch Anweisung



cathartik
26-09-2007, 10:31
Hallo,
ich versuch grad ne linux lib unter windows ans laufen zu kriegen. unter linux mit gcc lässt sie sich problemlos bauen.
nun gibts da im quellcode haufenweise switch anweisungen in folgender form:


switch(x){
case 0x01 ... 0xC:
do_this();
break
}

Damit komt der MSVS compiler nicht klar. Ich hab auch keine ahnung ob das überhaupt standard c konform ist.
Ich vermute einfach mal, dass die entsprechende anweisung ausgeführte werden soll wenn x einen wert zwischen 0x01 und 0xC annimmt.
Gibts da vielleicht ne schmerzfreie variante, wie ich meinem compiler das beibiegen kann?

Mir liegt an dieser stelle nicht daran sämtliche switch anweisungen durch if-abfragen zuersetzen, weil das einfach verflucht of vorkommt :)

Gruß
cat

anda_skoa
26-09-2007, 14:33
Gibt es in diesen switch Blöcken mehrere solche Ranges, oder immer nur eine?

Im zweiten Fall könnte man sowas machen



switch (x)
{
case 0xFF: // was auch immer, nur ein Beispiel
break;

default:
if (x >= 0x01 && x <= 0xC)
{
// block der case Anweisung mit Range
}
else
{
// ursprünglicher default Block
}
break;
}


Ciao,
_

jeebee
26-09-2007, 14:48
#include <stdio.h>

int main(int argc, char *argv[]) {
switch(argc) {
case 1 ... 5:
printf("invoked with less than or equal to five (5) arguments\n");
break;
case 6 ... 10:
printf("invoked with more than five (5) and less than or equal to ten (10) arguments\n");
break;
default:
printf("invoked with more than ten (10) arguments\n");
}

return 0;
} gibt keine Fehler wenn ich es wie folgt kompiliere:
gcc -ansi -Wall switch.c Also ist diese switch-Variante nach ANSI C korrekt.

locus vivendi
26-09-2007, 16:13
[...] gibt keine Fehler wenn ich es wie folgt kompiliere:
Code:
gcc -ansi -Wall switch.c
Also ist diese switch-Variante nach ANSI C korrekt.
Das GCC Manual sagt:
"`-ansi'
In C mode, support all ISO C90 programs. In C++ mode, remove GNU
extensions that conflict with ISO C++."
und
"The `-ansi' option does not cause non-ISO programs to be rejected
gratuitously. For that, `-pedantic' is required in addition to
`-ansi'."

Das sieht nicht danach aus, dass man aus erfolgreicher Kompilierung schließen kann, das das Programm keine GCC-Erweiterung benutzt.

panzi
26-09-2007, 17:30
Hierbei handelt es sich um eine GNU extension: http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_4.html#SEC82

panzi
26-09-2007, 17:34
Bei kurzen ranges wäre auch das eine möglichkeit:


switch (x) {
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
...
break;
case 7: case 8: case 9: case 10: case 11: case 12:
...
}

jan61
26-09-2007, 17:41
Moin,

ANSI-C ist das meiner Meinung nach nicht, ich kann mich erinnern, dass der Solaris-Compiler auch über solche Konstrukte stolpert. Es gibt mehrere Möglichkeiten, das zu umgehen:


switch(x) {
case 0x01:
case 0x02:
/* usw. fuer alle Werte im Bereich einen leeren case anlegen */
case 0x0C:
do_this();
break;
}Schön ist das nicht. Der Knackpunkt ist, dass der switch in der ANSI-Form bei den case-Argumenten genau einen konstanten (int oder char)-Wert erwartet.

Eine andere Möglichkeit des Workarounds wäre es, eine Funktion oder ein Makro zu bauen, die als switch-Argument dient und einen eindeutigen Wert (z. B. den des höchsten Werts der Range) zurückliefert (ungetestet):


#define DO_RANGE(x) (x>0x00 && x<0x0D ? 0x0C : (x==0x00 ? 0x00 : (x<0x10 ? 0x0F : x)))
char do_range(char x) {
return(x>0x00 && x<0x0D ? 0x0C : (x==0x00 ? 0x00 : (x<0x10 ? 0x0F : x)));
}
...
switch(DO_RANGE(x)) {
...
}
switch(do_range(x)) {
...
}Das hängt davon ab, wie viele Wertebereiche es abzufragen gibt und es ist natürlich nur eine Verbrämung einer if-else-Struktur, aber manchmal macht es die Sache übersichtlicher.

Jan

jeebee
26-09-2007, 18:04
hmm, stimmt, hab das -pedantic vergessen, damit gibts ne Warnung.

MfG und danke für den Hinweis