Jump to content
  • Advertisement
Sign in to follow this  
ZealousEngine

Switch cases arent unique translation units?

This topic is 4471 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Am I missing something or is the following SUPPOSED to not work...

switch ( myVar ) {

   case 0:
      int test; 
      break;

   case 1:
      int test; //already declared, wont compile
      break;
}



I guess you just have to declare all your variables outside any case?

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by ZealousEngine
Am I missing something or is the following SUPPOSED to not work...

*** Source Snippet Removed ***

I guess you just have to declare all your variables outside any case?

That is not supposed to work, yes. You can define it outside the case, or do this:

switch ( myVar ) {

case 0: { //<-------------------
int test;
break;
} //<-------------------
case 1: { //<-------------------
int test;
break;
} //<-------------------
}

The braces define new blocks, within which you can define whatever you like.

CM

Share this post


Link to post
Share on other sites
Also note that what you are referring to are blocks, not translation units. A translation unit refers to an entire c/cpp file and all headers that it includes during the process of compiling.

Share this post


Link to post
Share on other sites
In fact, you can create a scope around basically any sequence of statements - you don't need to have a for/if/while/etc. The key is that cases in a switch statement are separated by case labels; i.e. they do not introduce their own scopes naturally, but you are always able to add them in.

This technique is not often seen, but can be used for several purposes:

- in switch statements, as demonstrated

- to "group" logical blocks of code in a function (although you can probably just use whitespace, and your function might be too long at this point anyway)

- to force a destructor to be called at a specific point (for example, as a way of closing an iostream object without explicitly using .close(), or to make use of side effects of the destructor - it is common, for example, to do timing/profiling of code by storing the current time in the constructor and calculating and doing something with the difference in the destructor)

- to "reclaim" a variable name for another variable of a different type (but again, your function might be too long, and you probably shouldn't want to reuse the name)

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
This technique is not often seen, but can be used for several purposes:

- in switch statements, as demonstrated

- to "group" logical blocks of code in a function (although you can probably just use whitespace, and your function might be too long at this point anyway)

- to force a destructor to be called at a specific point (for example, as a way of closing an iostream object without explicitly using .close(), or to make use of side effects of the destructor - it is common, for example, to do timing/profiling of code by storing the current time in the constructor and calculating and doing something with the difference in the destructor)

- to "reclaim" a variable name for another variable of a different type (but again, your function might be too long, and you probably shouldn't want to reuse the name)

Indeed. I often use it in "throwaway" (typically single-file) Win32 C++ code as a means of disposing of interim objects without polluting the local namespace:

...
ATOM a;

{
WNDCLASSEX wcx;
// <rest of wndclass declaration>
a = RegisterClassEx(&wcx);
}
...
UnregisterClass(MAKEWORD(a, NULL));

Share this post


Link to post
Share on other sites
Quote:
Original post by ZealousEngine
Ahhh cool I didnt know you could use brackets with this : .

Also note that you can place a label prior to any statement (case labels, however, are restricted to occuring within switch statements).

In C and C++, a statement block can occur anywhere a statement can. A statement block is a series of statements delimited by a pair of curly braces ({}). It is this language property that provides the flexibility to omit braces in the bodies of if, for, while and else. Those constructs actually accept statements, but since a statement block is valid pretty much wherever a statement is, the result is this sort of flexibility:
if (condition)
while (otherCondition)
{
if (discriminant)
statement;
else
{
// statement-block
}
}

You must use braces with the while statement here because if-else is a compound statement pair; parse errors would result otherwise. (As an aside, this is why Python decided to drop the braces altogether: if statements and statement blocks are generally syntactically substitutable, and we indent code as a mnemonic assist to indicate scope, then the braces are largely superfluous. Cases like the while above support that notion.)

Don't go too crazy with it, though, or your code will rapidly become unreadable.

Share this post


Link to post
Share on other sites
Its also worth noting that for loops are (or at least can be, such as with /Zc:forScope using the MSVC++ compiler) an exception to this rule. Technically, they should work like this:


for (int i = 0; i < 10; )
{ //<--------------------start new scope here
++i;
} //<--------------------end new scope
/*Normally, this will destroy the variable i, but if you were stringently following the standard,
i is not in the same scope as the for loop body and would still be around*/


...

//(later in same function)
for (int i = 20; i > 0;) //<-----if for loops followed the scope rule, this would be a redefinition error
{
--i;
}






Share this post


Link to post
Share on other sites
Ah, no, actually, that is the CORRECT behavior. Variables declared in the 'for header' belong to the scope of the 'for body'. Previous versions of MSVC had this wrong, and the compiler switch is included for backwards compatibility.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!