[comp.lang.c] switch vs. initializing declarations

jeff@ingres.com (Jeff Anton) (09/15/90)

A few days ago, it occured to me that I didn't have a good feeling
as to what the following code fragment which seems to be legal C
means.  This is a retorical question and is not real world code, but I
would like to hear from someone who has a good knowledge of the
formal C specifications.  Please reply to me personally as I don't
often read comp.lang.c but post to comp.lang.c if you wish.

main(argc, argv)
int	argc;
char	*argv[];
{
	switch (argc) {
		int	v = 1;

	default:
		v += 5;
	case 1:
		printf("%d\n", v);
	}
	return 0;
}


The ambiguity is whether or not 'v' should be initialized or not.
All compilers I've tested recognize the declaration but do not
do the initialization.  Some report line 6 statement not reached when
clearly the statement does have the declaritoy effect.  I could not decide
what is correct from K&R 1 but due to a sentence that said an initialization
with a declaration was a shorthand syntax I kind of expected what I got
from the compilers.

Can someone present a case that the initialization should have occured or
prove that it should not?
					Jeff Anton
					INGRES Co.

john@chinet.chi.il.us (John Mundt) (09/16/90)

In article <1990Sep14.204028.21189@ingres.Ingres.COM> jeff@ingres.com (Jeff Anton) writes:
>A few days ago, it occured to me that I didn't have a good feeling
>as to what the following code fragment which seems to be legal C
>means.  This is a retorical question and is not real world code, but I
>would like to hear from someone who has a good knowledge of the
>formal C specifications.  Please reply to me personally as I don't
>often read comp.lang.c but post to comp.lang.c if you wish.
>
>main(argc, argv)
>int	argc;
>char	*argv[];
>{
>	switch (argc) {
>		int	v = 1;
>
>	default:
>		v += 5;
>	case 1:
>		printf("%d\n", v);
>	}
>	return 0;
>}
>
>
>The ambiguity is whether or not 'v' should be initialized or not.
>All compilers I've tested recognize the declaration but do not
>do the initialization.  Some report line 6 statement not reached when
>clearly the statement does have the declaritoy effect....

I'm surprised it compiles, but it does.  Line 6 is not reached because
it is not within any of the case statements.  Therefore, there is no
argument you can give to argc which will reach the "case" of 
int	v = 1; so it is never executed.

It runs probably because most compilers assign a type of int to
variables and functions not specifically declared.  lint
has this to say about the program:

warning: statement not reached
    (6)  	
-- 
---------------------
john@admctr.chi.il.us
John Mundt   Teachers' Aide, Inc.  P.O. Box 1666,  Highland Park, IL
(708) 998-5007 || -432-8860 

eyal@echo.canberra.edu.au (Eyal Lebedinsky) (09/16/90)

>In article <1990Sep14.204028.21189@ingres.Ingres.COM> jeff@ingres.com (Jeff Anton) writes:
>A few days ago, it occured to me that I didn't have a good feeling
>as to what the following code fragment which seems to be legal C
>means.  This is a retorical question and is not real world code, but I
>would like to hear from someone who has a good knowledge of the
>formal C specifications.  Please reply to me personally as I don't
>often read comp.lang.c but post to comp.lang.c if you wish.
>
>main(argc, argv)
>int	argc;
>char	*argv[];
>{
>	switch (argc) {
>		int	v = 1;
>
>	default:
>		v += 5;
>	case 1:
>		printf("%d\n", v);
>	}
>	return 0;
>}
>
>
>The ambiguity is whether or not 'v' should be initialized or not.
>All compilers I've tested recognize the declaration but do not
>do the initialization.  Some report line 6 statement not reached when
>clearly the statement does have the declaritoy effect....
>
the 'switch' is like any goto. If you enter a block NOT through the
beginning then you cannot trust initialising code. It is generaly not
a good thing to do, and in the 'switch' statement you NEVER enter at
the begining, so don't initialize . If you insist on having an initialized
'v = 1' then make it external to the 'switch', maybe:

	{	int v = 1;
		switch (....) {
		...
		}
		return 0;
	}

Regards
	Eyal

-- 
Regards
	Eyal

eager@ringworld.Eng.Sun.COM (Michael J. Eager) (09/19/90)

In article <1990Sep16.005308.8804@chinet.chi.il.us> john@chinet.chi.il.us (John Mundt) writes:
>In article <1990Sep14.204028.21189@ingres.Ingres.COM> jeff@ingres.com (Jeff Anton) writes:
>>A few days ago, it occured to me that I didn't have a good feeling
>>as to what the following code fragment which seems to be legal C
>>means.  This is a retorical question and is not real world code, but I
>>would like to hear from someone who has a good knowledge of the
>>formal C specifications.  Please reply to me personally as I don't
>>often read comp.lang.c but post to comp.lang.c if you wish.
>>
>>main(argc, argv)
>>int	argc;
>>char	*argv[];
>>{
>>	switch (argc) {
>>		int	v = 1;
>>
>>	default:
>>		v += 5;
>>	case 1:
>>		printf("%d\n", v);
>>	}
>>	return 0;
>>}
>>
>>
>>The ambiguity is whether or not 'v' should be initialized or not.
>>All compilers I've tested recognize the declaration but do not
>>do the initialization.  Some report line 6 statement not reached when
>>clearly the statement does have the declaritoy effect....
>
>I'm surprised it compiles, but it does.  Line 6 is not reached because
>it is not within any of the case statements.  Therefore, there is no
>argument you can give to argc which will reach the "case" of 
>int	v = 1; so it is never executed.

Shouldn't really be surprising.  The definition of the switch statement
is 
	switch (<expr>) <statement>  

That is any statement.  There is no requirement that it be a compound
statement with case labels, or anything that looks reasonable.  
When I (and many others) commented on this to the ANSI committee, the 
answer was that cleaning up the syntax would break existing code.
Or was that existing crud?


>
>It runs probably because most compilers assign a type of int to
>variables and functions not specifically declared.  lint
>has this to say about the program:
>

Not quite.  C does give a default int declaration for undeclared 
functions, but it REQUIRES all variables to be defined.  The code
fragment has a valid declaration for the variable v and it is only
reference within the scope in which it is declared.