473,761 Members | 5,839 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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(somethin g)
{
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(somethin g)
{
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 2112
"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(somethin g)
{
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_Keit h) 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.orgw rote:
"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(somethin g)
{
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.orgw rote:
>"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.orgw rote:
>"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(somethin g)
{
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_Keit h) 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.orgw rote:
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_Keit h) 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.n ews.easynews.co m>,
"Robbie Hatley" <se************ **@for.my.email .addresswrote:
"Keith Thompson" <ks***@mib.orgw rote:
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.ne t - If your "From:" address isn't on my whitelist,
or the subject of the message doesn't contain the exact text "PopperAndShado w"
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
7380
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 variable. Select Case Number1 ' Evaluate Number1. Case 1 To 5 ' Number1 between 1 and 5, inclusive.
3
1704
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 ago. Any ideas what happened, or how to fix? I thought I could change every letter C to lower case, and then change every c that starts a word to an upper case C, but I don't know how to do the second step.
5
29065
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 Case" (with spaces). Thanx! -- Greg Collins Please visit: http://www.InfoPathDev.com
7
1780
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 deleted on End Select. How can I make it available for my loop?
2
2963
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 7 : retVal.Append("2") Case 10 : retVal.Append("3") Case 15 : retVal.Append("4") Case 20 : retVal.Append("5")
9
5311
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 this variable is not empty. The message is shown using the "alert()" function. The page works good in almost all the case, but some users have reported to my that the alert window don't appear.
13
1723
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 #include <iostream> #include <string> int main(int argc, char*argv}
0
9554
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10136
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
9925
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9811
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6640
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5266
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5405
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3913
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2788
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.