|
Programming C, bash, Python, Perl, PHP, Java, you name it. |
|
Thread Tools | Display Modes |
|
|||
Increment ordering
Hello,
I am writing a program and came across a strange quirk. I'm not sure what the standard is so I thought I asked you. I compiled it on Slackware 12.1 with gcc 4.2.3 and got one result, and compiled it on Solaris (version 10.x, I think) with gcc 3.3.6. Here's the code: Code:
variable1 = variable1++ % 2; /* same as variable1 = (variable1 % 2) + 1; -- this works on Slackware with gcc 4.2.3 */ /* on Solaris with gcc 3.3.6 - this is the same as variable1 = (variable1 + 1) % 2; */ Code:
variable1 = (variable1 % 2) + 1; But, I'm wondering which is the more correct and closer to standard C? Does one make a difference for code efficiency and optimization (obviously one affects portability)?
__________________
And the WORD was made flesh, and dwelt among us. (John 1:14) |
|
|||
It is a operator precedence issue. In the OpenBSD ksh you see something similar
Code:
$ cat round game=1 for x in 1 2 3 4 5 ; do echo Game nr: $game Player: $(( game++ % 2 + 1 )) done echo ---------- game=1 for x in 1 2 3 4 5 ; do echo Game nr: $game Player: $(( ++game % 2 + 1 )) done echo ---------- game=1 for x in 1 2 3 4 5 ; do echo Game nr: $game Player: $(( game % 2 + 1 )) game=$((++game)) done Code:
$ sh round Game nr: 1 Player: 2 Game nr: 2 Player: 1 Game nr: 3 Player: 2 Game nr: 4 Player: 1 Game nr: 5 Player: 2 ---------- Game nr: 1 Player: 1 Game nr: 2 Player: 2 Game nr: 3 Player: 1 Game nr: 4 Player: 2 Game nr: 5 Player: 1 ---------- Game nr: 1 Player: 2 Game nr: 2 Player: 1 Game nr: 3 Player: 2 Game nr: 4 Player: 1 Game nr: 5 Player: 2
__________________
You don't need to be a genius to debug a pf.conf firewall ruleset, you just need the guts to run tcpdump |
|
||||
The result of the above statement is "undefined" by the C standard.
This is because "variable1" is being modified more than once without any sequence point in between the modifications. |
|
||||
Thanks, ephemera. To clarify the confusion behind my first statement: The precidence specifies what the ++ applies to (giving meaning to the RHS), but of course it does not define when the side-effect increment takes place (i.e., either before or after the = assignment).
|
|
|||
I initially had it using pre-increment. But, it switched between 0 and 1 and I wanted it to switch between 1 and 2 -- and I have bigger fish to fry in this project (the main point is to create a game AI system). It is working the way it should with
variable1 = (variable1 % 2) + 1; . I was just wondering why one version of the compiler incremented after the rest of the statement and the other did it in the middle. And thanks to ephemera's post, I seem to have gotten my answer. It must just be a gcc quirk to allow non-standard C. Arrgh! C'mon pcc!
__________________
And the WORD was made flesh, and dwelt among us. (John 1:14) |
|
|||
Wow! That's nifty.
__________________
And the WORD was made flesh, and dwelt among us. (John 1:14) |
|
||||
In the future, rather than modulo by 2 you should binary and by 1 (afterall a number cannot be odd if the 1 bit is not set). Maybe a good compiler would catch and optimize that anyway, but it's always good to be certain.
But surely, in this case, a sub is even better. |
|
|