By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,837 Members | 1,813 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,837 IT Pros & Developers. It's quick & easy.

can't understand this weird case

P: n/a
Hi,guys!
I'm reading Stephen Dewhurst's book "C++ Gotchas"úČin gothca #7, I
meet a weird case:
bool Postorder::next() {
switch (pc)
case START:
while (true)
if (!child()) {
pc = LEAF;
return true;
case LEAF:
while (true)
if (sibling())
break;
else if (parent()) {
pc = INNER;
return true;
case INNER: ;
} else {
pc = DONE;
case DONE: return false;
}
}
}
I can't understand how the case goes, those cases are not even in the
same level, the author does not explain how the cases execute, could you
please help me with this? Any help is appreciated, thanks!
Jul 10 '06 #1
Share this Question
Share on Google+
5 Replies


P: n/a
"Frederick Dean" <di*******@tom.comwrote in message
news:e8**********@news.cn99.com...
: Hi,guys!
: I'm reading Stephen Dewhurst's book "C++ Gotchas"úČin gothca #7, I
: meet a weird case:
[...]
: I can't understand how the case goes, those cases are not even in the
: same level, the author does not explain how the cases execute, could you
: please help me with this? Any help is appreciated, thanks!

The loss of indentation in your post makes it even more difficult
to read this code.
I would guess that this example intends to illustrate that
the "case" labels of a switch statement are pretty much like
the labels of a goto: they can be used to jump anywhere within
other bracketed statements
[provided that no variable initialization is skipped].
switch(i) {
case a: ...
case b: ...
default: ...
}

is equivalent to:

if(i==a) goto label_a;
else if(i==b) goto label_b; //NB: i is not re-evaluated
else goto label_default;
{
label_a: ...
label_b: ...
label_default: ...
}

This can sometimes be abused to implement state machines
(as appears to be the case in the provided example) or
other nifty tricks (ever heard of Duff's device? see
http://en.wikipedia.org/wiki/Duff's_device).
But these special switch tricks are never a good idea,
except if the code is much messier without them...
[ as is the case for usage of goto ]
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
Brainbench MVP for C++ <http://www.brainbench.com
Jul 10 '06 #2

P: n/a

Frederick Dean wrote:
Hi,guys!
I'm reading Stephen Dewhurst's book "C++ Gotchas",in gothca #7, I
meet a weird case:
bool Postorder::next() {
switch (pc)
case START:
while (true)
if (!child()) {
pc = LEAF;
return true;
case LEAF:
while (true)
if (sibling())
break;
else if (parent()) {
pc = INNER;
return true;
case INNER: ;
} else {
pc = DONE;
case DONE: return false;
}
}
}
I can't understand how the case goes, those cases are not even in the
same level, the author does not explain how the cases execute, could you
please help me with this? Any help is appreciated, thanks!
I think this code has nothing to do with goto.

please provide a minimal understandable code. If you can provide the
complete Postorder class, that's better or atleast tell

me if it is available online.

after my own indentation, I could write it as follows..

bool Postorder::next()
{
switch (pc)
case START:
while (true)
if (!child())
{
pc = LEAF;
return true;
case LEAF:
while (true)
if (sibling())
break;
else if (parent())
{
pc = INNER;
return true;
case INNER: ;
}
else
{
pc = DONE;
case DONE:
return false;
}
}
}

The above program has following flaws..

The program enters into switch only if the case is START.
There is no reason for putting a while(true) infinite loop.
infinit while loop breaks if and only if the return value of child()
function is false or 0.
the program cannot enter into case LEAF: statement at any case.
so starting from that point, the code is useless.

-- Murali Krishna.

Jul 11 '06 #3

P: n/a

Murali Krishna wrote:
Frederick Dean wrote:
Hi,guys!
I'm reading Stephen Dewhurst's book "C++ Gotchas",in gothca #7, I
meet a weird case:
bool Postorder::next() {
switch (pc)
case START:
while (true)
if (!child()) {
pc = LEAF;
return true;
case LEAF:
while (true)
if (sibling())
break;
else if (parent()) {
pc = INNER;
return true;
case INNER: ;
} else {
pc = DONE;
case DONE: return false;
}
}
}
I can't understand how the case goes, those cases are not even in the
same level, the author does not explain how the cases execute, could you
please help me with this? Any help is appreciated, thanks!

I think this code has nothing to do with goto.

please provide a minimal understandable code. If you can provide the
complete Postorder class, that's better or atleast tell

me if it is available online.

after my own indentation, I could write it as follows..

bool Postorder::next()
{
switch (pc)
case START:
while (true)
if (!child())
{
pc = LEAF;
return true;
case LEAF:
while (true)
if (sibling())
break;
else if (parent())
{
pc = INNER;
return true;
case INNER: ;
}
else
{
pc = DONE;
case DONE:
return false;
}
}
}

The above program has following flaws..

The program enters into switch only if the case is START.
There is no reason for putting a while(true) infinite loop.
infinit while loop breaks if and only if the return value of child()
function is false or 0.
the program cannot enter into case LEAF: statement at any case.
so starting from that point, the code is useless.

-- Murali Krishna.
I thought atleast one person will point out my errors. No one did.

I want to sincerely confess myself that my previous posting is not
correct.

I am writing this because some readers may consider that to be a
correct answer.

As Ivan said switch acts like a goto, it's correct. I never thought the
case statement can be written inside any block. Infact, I never wrote
in that way.

I think Stephen Dewhurst wanted to tell that there are people like me
who would confuse with switch-case statements. He shows how swith-case
can also be written.

OK, finally what I learnt is..

the case statement can be written any where even inside a while block.

in the above code, when the valid case is met, the control jumps to
that case statement.

Do I have to learn any thing more? Please let me know.

-- Murali Krishna

Jul 11 '06 #4

P: n/a
Frederick Dean wrote:
Hi,guys!
I'm reading Stephen Dewhurst's book "C++ Gotchas"úČin gothca #7, I
meet a weird case:
bool Postorder::next() {
switch (pc)
case START:
while (true)
if (!child()) {
pc = LEAF;
return true;
case LEAF:
while (true)
if (sibling())
break;
else if (parent()) {
pc = INNER;
return true;
case INNER: ;
} else {
pc = DONE;
case DONE: return false;
}
}
}
I can't understand how the case goes, those cases are not even in the
same level, the author does not explain how the cases execute, could you
please help me with this? Any help is appreciated, thanks!
Try googling for Duff's Device (it's even in the English wikipedia),
this exposes a very similiar situation of a loop in the middle of a
switch statement. There was a long debate whether Duff's Device was
legal C, and in the end it was agreed that it must be regarded as legal.
Of course, such optimizations are highly coupled and should be
documented pretty well (in the above case, I would expect an explanation
of about two times the number of code lines).

Regards,
Stuart
Jul 14 '06 #5

P: n/a

Ivan Vecerina wrote:
"Frederick Dean" <di*******@tom.comwrote in message
news:e8**********@news.cn99.com...
: Hi,guys!
: I'm reading Stephen Dewhurst's book "C++ Gotchas"úČin gothca #7, I
: meet a weird case:
[...]
: I can't understand how the case goes, those cases are not even in the
: same level, the author does not explain how the cases execute, could you
: please help me with this? Any help is appreciated, thanks!
[snip]
switch(i) {
case a: ...
case b: ...
default: ...
}

is equivalent to:

if(i==a) goto label_a;
else if(i==b) goto label_b; //NB: i is not re-evaluated
else goto label_default;
{
label_a: ...
label_b: ...
label_default: ...
}
since the switch is only a conditional jump, I would use goto in the
case above

many would not believe me, but goto can turn state-machines code
clearer

Jul 14 '06 #6

This discussion thread is closed

Replies have been disabled for this discussion.