TIP: Click on subject to list as thread! ANSI
echo: c_plusplus
to: NEIL HELLER
from: DARIN MCBRIDE
date: 1997-08-26 08:24:00
subject: Why the braces?

 -=> Quoting Neil Heller to All
 NH> I always thought that one of the features of C++ is that variables
 NH> can be declared ANYWHERE (such as near where you're going to use them).
 NH> However I ran across a situation in MSVC 1.6 with a CPP module that
 NH> seems to contradict this.  Can someone explain to me why?
Yup, someone can.  Probably not me, but I'll give 'er a go anyway.  ;-)
 NH> If I write a switch statement thusly, I get compiler errors:
 NH> switch (foo) {
 NH> case 1 :
 NH> int bar = 2;
 NH> break;
 NH> case 2 :
 NH> int bar = 3;
 NH> break;
 NH> }
What are the compiler errors?  IIRC, without jumping around to my compilers,
I believe you'd get something along the lines of jumping over the
initialization of bar.  If you'd rename them to bar1 and bar2, you'd notice
that your case 2 jumps past the initialization of bar1.  That's because a
switch is basically a glorified goto - and bar1 is still in scope at case 2.
 NH> However, if I write the code this way there are no errors:
 NH> switch (foo) {
 NH> case 1 : {
 NH> int bar = 2;
 NH> break;
 NH> }
 NH> case 2 : {
 NH> int bar = 3;
 NH> break;
 NH> }
 NH> }
Notice here that bar1 is out of scope at case 2.  That is, any effects it MAY
have had are eliminated.
You'd notice the same type of trouble in:
void foo()
{
   // ...
   if (bar != NO_ERROR)
     goto exit;
   int baz = 3; // error!
exit:
   // cleanup code
}
The reason becomes much clearer if I rewrite the code after the label as:
exit:
   switch(baz)
   {
   // ...
   };
}
In the case of bar != NO_ERROR, which case will the switch take?  Dunno - baz
hasn't been initialized.  The simple, obvious, and wrong, method is for the
compiler to "move" baz to the top silently.  But what if baz isn't an int? 
Take, for example, baz as a string:
void foo()
{
   int bar;
   // do stuff with bar.
   if (bar != NO_ERROR)
     goto exit;
   string baz(itoa(bar));
   // do other stuff to baz
exit:
   if (baz == "something")
   {
     // ...
   }
   else if (baz == "something else")
   {
     // ...
   }
   else
   {
     // ...
   }
}
Now what?
The language decided to say no to jumping past definitions that remain in
scope.  Much simpler.  And it works.  ;-)
However, the side effect, intended or not, is that the case labels act the
same way.  Your new variables must be out of scope before the next case
label.  By putting in the braces with the closing brace before the next case
statement, you are doing exactly this: taking your new variable from the
previous case out of scope.
 NH> I was under the assumption that the braces weren't necessary in C++ as
 NH> far as declaring variables is concerned.  Why then do I need the
 NH> braces?  Do the added braces affect portability in any way?
Since it's required by the standard, the only affect on portability better be
positive.  :-)
Hope this helps.  :->
... Yes-men: Fellows who hang around the man nobody noes.
--- FastEcho 1.46
---------------
* Origin: House of Fire BBS - Toronto - (416)601-0085 - v.34 (1:250/536)

SOURCE: echomail via exec-pc

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.