473,224 Members | 1,299 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,224 software developers and data experts.

Declaring variables in "case" blocks?


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;
}
}
}

Is there anything wrong with that? Does it violate some rule
of C that I'm missing? It's almost as if the first time I
try to read Dumvar in the code, it's being redeclared (as int),
redefined, and reinitialized to 0.

When I moved the declaration of DumVar up to the top of the
function, it now works correctly:

int Function (int something-)
{
int DumVar = 72;
switch(something)
{
case WHATEVER:
{
// Code here now sees the value of DumVar as being 72
break;
}
}
}

So am I just missing something, or is my compiler buggy?

(I'm using National Instruments "CVI" compiler for this;
I haven't tested this on a more common compiler such as GCC.)

--
Cheers,
Robbie Hatley
lone wolf aatt well dott com
triple-dubya dott Tustin Free Zone dott org
Jul 31 '07 #1
9 2064
"Robbie Hatley" <se**************@for.my.email.addresswrites:
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. The above is valid, and code that refers to DumVar will
see its value as 72. You'd have been better off posting a small
compilable program, so you could confirm that the problem is still
there.

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;
}

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.

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.

For more fun with switch statements, see question 20.35 in the
comp.lang.c FAQ, <http://www.c-faq.com/(Duff's Device).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <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"
Jul 31 '07 #2

"Keith Thompson" <ks***@mib.orgwrote:
"Robbie Hatley" <se**************@for.my.email.addresswrites:
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'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.

I'm truly perplexed. I'll have to try to reproduce this bizarre
bug again.
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:
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.
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!

--
Cheers,
Robbie Hatley
lone wolf aatt well dott com
triple-dubya dott Tustin Free Zone dott org
Jul 31 '07 #3
Robbie Hatley wrote, On 31/07/07 21:20:
"Keith Thompson" <ks***@mib.orgwrote:
>"Robbie Hatley" <se**************@for.my.email.addresswrites:
<snip>
>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.
<snip>

This is why you should always reduce your code to a small compilable
example that exhibits the problem (obviously, if the problem is it not
compiling then it does not need to be compilable!). There is no point
other people trying to debug a problem in code that does not exhibit the
problem.
--
Flash Gordon
Jul 31 '07 #4
"Robbie Hatley" <se**************@for.my.email.addresswrites:
"Keith Thompson" <ks***@mib.orgwrote:
>"Robbie Hatley" <se**************@for.my.email.addresswrites:
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) ks***@mib.org <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"
Jul 31 '07 #5

"Keith Thompson" <ks***@mib.orgwrote:
As for the problem you're having in your code, no offense,
None taken. :-)
but I don't believe that it's as you describe it.
I didn't save a copy of the version that had the problem,
but I did manually reconstruct it by moving the variable
declarations back into the block under the case label.

However, the problem did *NOT* recur!

I suspect now that it was something like this:

int Func(int x)
{
switch (x)
{
case 8:
{
int DumVar = 72;
char Blat[51] = {'\0'};
sprintf(Blat, "DumVar = %d\n", Dumvar); // ERROR
MessagePopup("!!!", Blat); // prints "DumVar = 0"
}
}
}

See the problem? It's on the line marked "ERROR". It's
almost invisible. Hint: has to do with case.

:-)

I'm about 80% certain now that something like that was the
problem. I can never be totally sure what happened, though.

Next time some bizarre bug like this happens, I'll
be sure to save a zip snapshot of source (my poor-man's
version of version control) before making any changes.
That way, I can post a stripped-down, compilable program
that actually does exhibit the bug.

Anyway, thanks for your help.

--
Cheers,
Robbie Hatley
lone wolf aatt well dott com
triple-dubya dott Tustin Free Zone dott org
Jul 31 '07 #6
"Robbie Hatley" <se**************@for.my.email.addresswrites:
[...]
I suspect now that it was something like this:

int Func(int x)
{
switch (x)
{
case 8:
{
int DumVar = 72;
char Blat[51] = {'\0'};
sprintf(Blat, "DumVar = %d\n", Dumvar); // ERROR
MessagePopup("!!!", Blat); // prints "DumVar = 0"
}
}
}

See the problem? It's on the line marked "ERROR". It's
almost invisible. Hint: has to do with case.
Got it. So you had a local variable named 'DumVar', and a variable in
an outer scope named 'Dumvar'? I assume you didn't use those names in
your actual code, but you might find that a more consistent naming
convention will help you avoid such problems in the future.

[...]
Next time some bizarre bug like this happens, I'll
be sure to save a zip snapshot of source (my poor-man's
version of version control) before making any changes.
That way, I can post a stripped-down, compilable program
that actually does exhibit the bug.
<OT>
Consider using an actual version control system. There are several
free ones out there, and they more than pay for themselves. (I use
RCS and CVS myself.)
</OT>

--
Keith Thompson (The_Other_Keith) ks***@mib.org <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"
Jul 31 '07 #7
On Tue, 31 Jul 2007 22:49:30 +0000, Robbie Hatley wrote:
I suspect now that it was something like this:

int Func(int x)
{
switch (x)
{
case 8:
{
int DumVar = 72;
char Blat[51] = {'\0'};
sprintf(Blat, "DumVar = %d\n", Dumvar); // ERROR
MessagePopup("!!!", Blat); // prints "DumVar = 0"
}
}
}

See the problem? It's on the line marked "ERROR". It's
almost invisible. Hint: has to do with case.
I wouldn't expect it to compile at all, unless there is a Dumvar
with a small v declared in an outer scope.
(And do they claim that CamelCase is better than dum_var because
you could unintentionally spell the latter with a wrong number of
underscores? Hum...)
--
Army1987 (Replace "NOSPAM" with "email")
"Never attribute to malice that which can be adequately explained
by stupidity." -- R. J. Hanlon (?)

Jul 31 '07 #8
In article <_%********************@fe08.news.easynews.com>,
"Robbie Hatley" <se**************@for.my.email.addresswrote:
"Keith Thompson" <ks***@mib.orgwrote:
As for the problem you're having in your code, no offense,

None taken. :-)
but I don't believe that it's as you describe it.

I didn't save a copy of the version that had the problem,
but I did manually reconstruct it by moving the variable
declarations back into the block under the case label.

However, the problem did *NOT* recur!

I suspect now that it was something like this:

int Func(int x)
{
switch (x)
{
case 8:
{
int DumVar = 72;
char Blat[51] = {'\0'};
sprintf(Blat, "DumVar = %d\n", Dumvar); // ERROR
MessagePopup("!!!", Blat); // prints "DumVar = 0"
}
}
}

See the problem? It's on the line marked "ERROR". It's
almost invisible. Hint: has to do with case.
If that's the actual problem, you would have (Or at least SHOULD have)
gotten an "undefined identifier: Dumvar" type of error from the
compiler, since, syntactically, that's exactly what you've got going on.

--
Don Bruder - da****@sonic.net - If your "From:" address isn't on my whitelist,
or the subject of the message doesn't contain the exact text "PopperAndShadow"
somewhere, any message sent to this address will go in the garbage without my
ever knowing it arrived. Sorry... <http://www.sonic.net/~dakiddfor more info
Jul 31 '07 #9
Robbie Hatley wrote:
I didn't save a copy of the version that had the problem,
but I did manually reconstruct it by moving the variable
declarations back into the block under the case label.

However, the problem did *NOT* recur!
Use valgrind or another memory access checker on problems
like this. One reason DumVar could have the wrong value
is an invalid memory access stomping on it. Putting in print
statements sometimes moves code around and "fixes" that sort
of problem, but not really of course.
>
I suspect now that it was something like this:
Didn't you keep the broken version of the program???
sprintf(Blat, "DumVar = %d\n", Dumvar); // ERROR
That should have thrown a compiler error, unless Dumvar was
declared elsewhere. Using both DumVar and Dumvar in the same function
would have been, well, "Dum"!

Regards,

David Mathog
Aug 1 '07 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

10
by: Lakshmi Narayanan.R | last post by:
Hi Experts, Using keyword "To" in select case giving error.The following code is got from www.microsrosoft.com itself. What is the wrong with this?. <% Dim Number1 Number1 = 7 ' Initialize...
3
by: MHenry | last post by:
All the lower case "c" in my database table are now upper case "C" starting in January 2004. All prior data is fine. I just noticed this after installing a Microsoft update patch a couple of days...
5
by: Greg Collins [InfoPath MVP] | last post by:
I couldn't find anything in my searches... I'm wondering if there's a Regex (with or without additional C# code) that can convert a either "lowerCamelCase" or "UpperCamelCase" into a proper "Title...
7
by: Shapper | last post by:
Hello, I have a "Select Case MyVar" in which I define the values of an Array according to the value of MyVar. I need to use the Array Values in a Loop after End Select. It seems the Array is...
2
by: Dave Markle | last post by:
Good afternoon. I was just going through my code, analyzing it with FXCop, and FxCop gave me the following error on this code: MY CODE: Select Case termYears Case 5 : retVal.Append("1") Case...
9
by: Tonio Tanzi | last post by:
I have an asp page with this tag <body onLoad="show_msg('<%=error_msg%>');"> where "show_msg" is a javascript function that shows the message contained in the asp variable "error_msg" only if...
13
by: Michael Bell | last post by:
Working my way through Koenig & Moo "Accelerated C++" and using Borlang Builder 5 (but that is probably not relevant) I reached exercise 1-1 and typed in #include <vcl.h> #pragma hdrstop...
1
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
0
by: VivesProcSPL | last post by:
Obviously, one of the original purposes of SQL is to make data query processing easy. The language uses many English-like terms and syntax in an effort to make it easy to learn, particularly for...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 3 Jan 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). For other local times, please check World Time Buddy In...
0
by: jianzs | last post by:
Introduction Cloud-native applications are conventionally identified as those designed and nurtured on cloud infrastructure. Such applications, rooted in cloud technologies, skillfully benefit from...
0
by: abbasky | last post by:
### Vandf component communication method one: data sharing ​ Vandf components can achieve data exchange through data sharing, state sharing, events, and other methods. Vandf's data exchange method...
2
by: jimatqsi | last post by:
The boss wants the word "CONFIDENTIAL" overlaying certain reports. He wants it large, slanted across the page, on every page, very light gray, outlined letters, not block letters. I thought Word Art...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: stefan129 | last post by:
Hey forum members, I'm exploring options for SSL certificates for multiple domains. Has anyone had experience with multi-domain SSL certificates? Any recommendations on reliable providers or specific...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.