Reputation: 25
I have been asked to comment some code and describe what it does. All was fine and I had a good handle on what was being done in the the cases of the switch but now I am unsure whether any of the cases are ever met. I don't have anyway to run or test this code currently as my main machine with all my regular software is down.
Does either of the cases of the switch get used besides the default with the conditions of this while loop? is i simply incremented to 32 and the rByte returned before it even makes the switch? What is with the ; after the conditions of the while? Shouldn't it be followed by {....} rather than ; ?
while(pCommand[--Ptr.Five] > 10 && ++i <32);
if(i==32)
{
return rByte;
}
switch(pCommand[Ptr.Five++])
{
case 2: ... (lots of code)
break;
case 4: ... (lots of cod)
break;
default: ...
break;
}
Also, how is the --Ptr.Five handled vs. the Ptr.Five++? My understanding is the first moves the pointer back and uses that value while the second uses the current value and post increments.
Am I missing something? Even moving past the ; after the conditions of the while and the lack of {} after the while, wouldnt the value of Ptr.Five be > 10 and therefore never be 2 or 4 ever?
With the ; behind the conditions of the while, would i just get bumped to32 and the following if would return the rByte?
Upvotes: 1
Views: 144
Reputation: 67713
while(pCommand[--Ptr.Five] > 10 && ++i <32);
doesn't have a body, but the loop condition itself has side-effects, so it does do something.
We could re-write this as:
while (1) {
--Ptr.Five;
if (pCommand[Ptr.Five] <= 10)
break;
++i;
if (i == 32)
break;
}
if (i == 32) {
/* we never hit the pCommand condition */
}
As for why:
pCommand
, from offset Ptr.Five
to at most 32 entries earlier, looking for a value <= 10
rByte
PtrFive
is incremented to indicate the next entry after this value, after the switch is dispatchedAlso, how is the --Ptr.Five handled vs. the Ptr.Five++? My understanding is the first moves the pointer back and uses that value while the second uses the current value and post increments.
That's exactly correct. In:
pCommand[--Ptr.Five] > 10
Ptr.Five
is decremented before the rest of the expression is evaluated, whereas in:
pCommand[Ptr.Five++]
the expression is evaluated with the old value of Ptr.Five
, and then it's incremented right after. Here, that means the switch is based on the old entry in pCommand
(the one that ended the while loop because it's <= 10
), but Ptr.Five
is incremented before code inside the cases executes.
A quick note on side-effects: as John Bode points out in a comment, my description of the pre-decrement and post-increment expressions isn't quite accurate.
This is because storing the new value into Ptr.Five
doesn't have to happen right away.
However since it does have to happen (as if) by the next sequence point, which is here the &&
, there's no real ambiguity.
This generally only becomes an issue if you string multiple interdependent side-effecting expressions together in a single statement. So, you know, try and avoid that.
Upvotes: 0
Reputation: 10613
It's impossible to answer your question. Even if we assume that i
starts at 0
, who knows what value pCommand[Ptr.Five]
has at the start of this code block?
Addressing some of the questions that can be answered, would it help if we rewrote the while
like this:
while(pCommand[--Ptr.Five] > 10 && ++i <32)
{
/* do nothing as the body of the loop... nothing at all.
* Everything happens in the condition.
*/
}
The syntax with the semicolon is valid, if a bit confusing at first: think of what the semicolon means in C/C++ (terminates a statement) and then think of what the statement being terminates is in this case (hint: it's a "no operation").
The difference between --Ptr.Five
and Ptr.Five--
is what you describe: the first variant (the pre-decrement) will decrement Ptr.Five
and then return the resulting value; the second variant (the post-decrement) will decrement the Ptr.Five
but return the value before the decrement.
Upvotes: 1
Reputation: 4380
Presuming i
started at 0
-- The while loop is parsing through 31 elements (1-31) of the pCommand
array, decrementing Ptr.Five
before checking the value, looking for a value that is less than 10
. If it does not find one, the function returns rByte
-- it then checks the value of pCommand[Ptr.Five]
before it increments... therefore, the value used in the switch is the same as the value used in the while
conditional. The value could well be any of the switch conditions as we know it is less than 10
Upvotes: 0
Reputation: 409146
The semicolon by itself is an empty statement. So doing e.g.
while (complicated_expression)
;
Is the same as:
while (complicated_expression)
{
}
It's often used when complicated_expression
has side-effects, so no loop body is needed.
Upvotes: 2
Reputation: 183883
The loop
while(pCommand[--Ptr.Five] > 10 && ++i <32);
decrements Ptr.Five
and increments i
until
pCommand[Ptr.Five] <= 10
, ori >= 32
,whichever happens first. Since the changes to the interesting variables are done in the loop condition, the loop body should be empty. (Not that it's particularly good style, but I've seen worse.)
If i == 32
, the switch
isn't reached, otherwise, if i < 32
, you know that pCommand[Ptr.Five] <= 10
, so both non-default cases can be reached.
Upvotes: 2