switch syntax and style

  • Thread starter Christopher Benson-Manica
  • Start date
C

Christopher Benson-Manica

I presume that putting the default case of a switch statement before
the others is legal, as in the following skeleton program:

#include <stdio.h>

int main( int argc, char *argv[] )
{
switch( (unsigned int)argc ) { /* just to be pedantically correct */
default:
printf( "%d arguments not handled...\n", argc-4 );
case 4:
/* do stuff with argv[3] */
case 3:
/* do stuff with argv[2] */
case 2:
/* do stuff with argv[1] */
case 1:
/* do stuff with argv[0] */
case 0:
/* do nothing */
break;
}
return 0;
}

If it is legal, is it stylistically acceptable and reasonably easy to
understand? (I have my doubts.)
 
D

Dave Vandervies

I presume that putting the default case of a switch statement before
the others is legal, as in the following skeleton program:

'Tis. default and case NN are just labels, and can go anywhere inside
the switch, as long as there's at most one of each.

#include <stdio.h>

int main( int argc, char *argv[] )
{
switch( (unsigned int)argc ) { /* just to be pedantically correct */

According to n869, you need something with an integer type here, but
there's no need for it to be unsigned. (6.8.4.2#1)
default:
printf( "%d arguments not handled...\n", argc-4 );
case 4:
/* do stuff with argv[3] */
case 3:
/* do stuff with argv[2] */
case 2:
/* do stuff with argv[1] */
case 1:
/* do stuff with argv[0] */
case 0:
/* do nothing */
break;
}
return 0;
}

If it is legal, is it stylistically acceptable and reasonably easy to
understand? (I have my doubts.)

Depends why you're doing it and whether a better way exists.
If the "do stuff with argv" is the same, you'll want to use a loop
instead:
--------
if(argc>4)
printf("%d arguments not handled...\n",argc-4);
for(i=3;i>=0;i--)
{
/*do stuff with argv*/
}
--------

What Are You Really Trying To Do?


dave
 
E

Emmanuel Delahaye

Christopher Benson-Manica a écrit :
I presume that putting the default case of a switch statement before
the others is legal, as in the following skeleton program:

#include <stdio.h>

int main( int argc, char *argv[] )
{
switch( (unsigned int)argc ) { /* just to be pedantically correct */
default:
printf( "%d arguments not handled...\n", argc-4 );
case 4:
/* do stuff with argv[3] */
case 3:
/* do stuff with argv[2] */
case 2:
/* do stuff with argv[1] */
case 1:
/* do stuff with argv[0] */
case 0:
/* do nothing */
break;
}
return 0;
}

If it is legal, is it stylistically acceptable and reasonably easy to
understand? (I have my doubts.)

It is perfectly legal and can make sense in some occasions, but don't
forget the 'break' thing, or comment it explicitely with

/* fall-thru */

You probably wanted:

#include <stdio.h>

int main( int argc, char *argv[] )
{
switch (argc)
{
default:
printf( "%d arguments not handled...\n", argc-4 );
break;
case 4:
/* do stuff with argv[3] */
/* fall-thru */
case 3:
/* do stuff with argv[2] */
/* fall-thru */
case 2:
/* do stuff with argv[1] */
/* fall-thru */
case 1:
/* do stuff with argv[0] */
/* fall-thru */
case 0:
/* do nothing */
}
return 0;
}
 
D

Dan Pop

In said:
I presume that putting the default case of a switch statement before
the others is legal, as in the following skeleton program:

#include <stdio.h>

int main( int argc, char *argv[] )
{
switch( (unsigned int)argc ) { /* just to be pedantically correct */
^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Huh?!?

1 The controlling expression of a switch statement shall have
integer type.

Since your program doesn't call main() recursively, there is no way
for argc to have a negative value. And if you are afraid of such a
possibility, converting it to a large positive value doesn't make any
sense in the context of your program...
default:
printf( "%d arguments not handled...\n", argc-4 );
case 4:
/* do stuff with argv[3] */
case 3:
/* do stuff with argv[2] */
case 2:
/* do stuff with argv[1] */
case 1:
/* do stuff with argv[0] */
case 0:
/* do nothing */
break;
}
return 0;
}

If it is legal, is it stylistically acceptable and reasonably easy to
understand? (I have my doubts.)

If it is simplifying the structure of your code, go for it! Your example
is certainly reasonable.

A switch is nothing more than a multidestination goto, with the added
restriction that all destinations must be within the same block. The
order of the various destinations is entirely dictated by the programmer's
needs.

From a stylistical point of view, unsurprisingly, there is no consensus.
The Pascal bigots will insist that falling through cases is absolute
heresy: the code handling each case must end with its own break statement,
so having the default case at the beginning is buying you nothing.

Dan
 
C

Christopher Benson-Manica

Dave Vandervies said:
'Tis. default and case NN are just labels, and can go anywhere inside
the switch, as long as there's at most one of each.

Just wanted to be sure I hadn't missed a sentence in K&R to the
opposite effect...
According to n869, you need something with an integer type here, but
there's no need for it to be unsigned. (6.8.4.2#1)

Yes. D'oh.
 
D

Dan Pop

In said:
Christopher Benson-Manica a écrit :
I presume that putting the default case of a switch statement before
the others is legal, as in the following skeleton program:

#include <stdio.h>

int main( int argc, char *argv[] )
{
switch( (unsigned int)argc ) { /* just to be pedantically correct */
default:
printf( "%d arguments not handled...\n", argc-4 );
case 4:
/* do stuff with argv[3] */
case 3:
/* do stuff with argv[2] */
case 2:
/* do stuff with argv[1] */
case 1:
/* do stuff with argv[0] */
case 0:
/* do nothing */
break;
}
return 0;
}

If it is legal, is it stylistically acceptable and reasonably easy to
understand? (I have my doubts.)

It is perfectly legal and can make sense in some occasions, but don't
forget the 'break' thing, or comment it explicitely with

/* fall-thru */

Sez who? When it is obvious from the program logic that the code is
deliberately falling through cases, such silly comments serve no purpose.

It's only when most cases have their own break statement and falling
through is the exception, rather than the rule, that such visual hints
are needed to indicate that the break was not accidentally forgotten.
You probably wanted:

#include <stdio.h>

int main( int argc, char *argv[] )
{
switch (argc)
{
default:
printf( "%d arguments not handled...\n", argc-4 );
break;

If you think he wanted this break, you completely missed his point.
The default label is at the beginning *precisely* because he wanted to
fall through! Otherwise, conventionally placing it at the end would
have been perfectly fine.

Try to use your brain creatively, instead of thinking in patterns!

Dan
 
C

Christopher Benson-Manica

Dan Pop said:
Since your program doesn't call main() recursively, there is no way
for argc to have a negative value. And if you are afraid of such a
possibility, converting it to a large positive value doesn't make any
sense in the context of your program...

I wasn't sure when argc was allowed to be negative, so I tried (and
failed) to handle the case properly. Oh well - "Huh??" indeed.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top