Re: Declaring variables in "case" blocks?
- From: Keith Thompson <kst-u@xxxxxxx>
- Date: Tue, 31 Jul 2007 14:09:58 -0700
"Robbie Hatley" <see.my.signature@xxxxxxxxxxxxxxxxxxxx> writes:
"Keith Thompson" <kst-u@xxxxxxx> wrote:
"Robbie Hatley" <see.my.signature@xxxxxxxxxxxxxxxxxxxx> writes:
Greetings, group. I just found a weird problem in a program where
a variable declared in a {block} after a "case" keyword was being
treated as having value 0 even though its actual value should
have been something else. An extremely stripped-down version:
int Function (int something)
{
switch(something)
{
case WHATEVER:
{
int DumVar = 72;
// Some code uses DumVar. It seems to see the value
// of DumVar as being 0 ! What the heck???
break;
}
}
}
I think you've stripped down your code so far that you've eliminated
the error.
Maybe so.
The above is valid
That's what I was wondering about. Thanks.
and code that refers to DumVar will see its value as 72.
Theoretically, yes.
In practice (in my program, with my compiler), I was seeing 0,
which is why I was so puzzled.
You weren't seeing 0 with the code that you posted. Without seeing
code that does display 0, I can't make any definitive comments.
You'd have been better off posting a small compilable program,
so you could confirm that the problem is still there.
I (mostly) did. If you #define WHATEVER, then call Function()
from main(), it will compile and run.
Hmmm... let me try that.
Ok, I just compiled and ran my stripped-down version here,
with a sprintf() of DumVar to a char buffer, and printed the buffer
in a popup message box. It displays as "72". Oops. Problem went
away. Weird.
There's nothing weird about it. The code you posted doesn't exhibit
the error.
You need to create your own complete stripped-down program, and run it
yourself to exhibit the error, *before* you post it here.
I'm truly perplexed. I'll have to try to reproduce this bizarre
bug again.
Please do.
Do you still have the original code that exhibited the problem? It's
probably too big to post here, but be sure you save a copy of it so
you can use it as a basis for creating something that you can post.
But here's an example that illustrates the problem you're having:
#include <stdio.h>
int main(void)
{
int x = 42;
switch(x) {
int DumVar = 72;
case 42:
printf("ok, x = %d, DumVar = %d\n", x, DumVar);
break;
default:
printf("Huh?\n");
break;
}
return 0;
}
Nice try, but that's not my problem. I was careful to put
the variable declaration at the top of a {block}, just under a
CASE label, like so:
#include <stdio.h>
int main(void)
{
int x = 42;
switch(x) {
case 42:
{
int DumVar = 72;
printf("ok, x = %d, DumVar = %d\n", x, DumVar);
break;
}
default:
printf("Huh?\n");
break;
}
return 0;
}
and I was getting "DumVar = 0". Definitely wasn't a large
value (uninitialized RAM garbage) as you're getting here:
Most likely you're mistaken, or perhaps you're having some other
problem that's not related to the switch statement.
The output I get is:
ok, x = 42, DumVar = 1628438944
after a compiler warning:
c.c:6: warning: unreachable code at beginning of switch statement
The problem is that control jumps directly from the 'switch' to the
appropriate 'case' label, in this case to 'case 42:'. After that,
DumVar is visible, but you've skipped over its initialization.
Yep! I've seen that one bite even highly-experienced co-workers.
Since your declaration is never executed, your compiler declares
the variable as int for you, allocates some memory, but doesn't
initialize it to anything. So it's value could be anything from
-(2^31) to +(2^31)-1. (Assuming 32-bit int, 2's comp. rep.)
You can safely declare variables within a block following a case
label, but not within a block that's the entire body of the switch
statement.
Well, you could... but the code will never execute.
The initializer, if any, will be skipped -- but the variable will
exist. This is not a good idea, though, since you can always declare
it in an outer scope.
For more fun with switch statements, see question 20.35 in the
comp.lang.c FAQ, <http://www.c-faq.com/> (Duff's Device).
Whoa! It's actually legal to jump into the middle of a do loop
that way?! Cool machine!
It's the language, not any particular machine. Duff's Device is legal
and portable (though there's some controversy about this).
A switch statement is a lower-level construct than it appears to be.
It's really nothing more than a computed goto within a single
statement (which can be a block). The error of skipping an initializer
in a switch statement is really no different than this:
#include <stdio.h>
int main(void)
{
goto LABEL;
{
int x = 42;
LABEL:
printf("x = %d\n", x);
}
return 0;
}
As for the problem you're having in your code, no offense, but I don't
believe that it's as you describe it. If you can post an actual
program that exhibits the problem (by "actual program" I mean
something that anyone else can copy-and-paste, compile, link, and
execute, with no modifications), then we'll be glad to look at it.
But all we've seen so far is code that doesn't exhibit the problem,
and code that does exhibit a problem but for reasons different from
what you describe.
It's possible that you've run across either an obscure corner of the
language that I'm not thinking of, or a compiler bug, but that's not
the way to bet.
--
Keith Thompson (The_Other_Keith) kst-u@xxxxxxx <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
.
- References:
- Declaring variables in "case" blocks?
- From: Robbie Hatley
- Re: Declaring variables in "case" blocks?
- From: Keith Thompson
- Re: Declaring variables in "case" blocks?
- From: Robbie Hatley
- Declaring variables in "case" blocks?
- Prev by Date: Re: Increment operator
- Previous by thread: Re: Declaring variables in "case" blocks?
- Next by thread: Calling a function with a literal list of strings?
- Index(es):
Relevant Pages
|