DaemonForums  

Go Back   DaemonForums > Miscellaneous > Programming

Programming C, bash, Python, Perl, PHP, Java, you name it.

Reply
 
Thread Tools Display Modes
  #1   (View Single Post)  
Old 18th November 2008
JMJ_coder JMJ_coder is offline
VPN Cryptographer
 
Join Date: May 2008
Posts: 464
Default 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; */
I need the code to switch between 1 and 2 - it is switching which turn it is in a two player game. I need it to work ultimately on Solaris, so I changed it to:
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)
Reply With Quote
  #2   (View Single Post)  
Old 18th November 2008
J65nko J65nko is offline
Administrator
 
Join Date: May 2008
Location: Budel - the Netherlands
Posts: 4,125
Default

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
A run produces:
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
Here only the second calculation "$(( ++game % 2 + 1 )) produces the desired result isn't it? How about trying this pre-increment variation
__________________
You don't need to be a genius to debug a pf.conf firewall ruleset, you just need the guts to run tcpdump
Reply With Quote
  #3   (View Single Post)  
Old 18th November 2008
IdOp's Avatar
IdOp IdOp is offline
Too dumb for a smartphone
 
Join Date: May 2008
Location: twisting on the daemon's fork(2)
Posts: 1,027
Default

My copy of K&R says (page 49) that ++ has higher precidence than % .

And now for something completely different way to skin the fish:

variable1 = 3 - variable1;

should toggle nicely between 1 and 2 (;.
Reply With Quote
  #4   (View Single Post)  
Old 18th November 2008
ephemera's Avatar
ephemera ephemera is offline
Knuth's homeboy
 
Join Date: Apr 2008
Posts: 537
Default

Quote:
Originally Posted by JMJ_coder View Post
[CODE]variable1 = variable1++ % 2;
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.
Reply With Quote
  #5   (View Single Post)  
Old 18th November 2008
IdOp's Avatar
IdOp IdOp is offline
Too dumb for a smartphone
 
Join Date: May 2008
Location: twisting on the daemon's fork(2)
Posts: 1,027
Default

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).
Reply With Quote
  #6   (View Single Post)  
Old 20th November 2008
JMJ_coder JMJ_coder is offline
VPN Cryptographer
 
Join Date: May 2008
Posts: 464
Default

Quote:
Originally Posted by J65nko View Post
How about trying this pre-increment variation
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)
Reply With Quote
  #7   (View Single Post)  
Old 20th November 2008
JMJ_coder JMJ_coder is offline
VPN Cryptographer
 
Join Date: May 2008
Posts: 464
Default

Quote:
Originally Posted by IdOp View Post
And now for something completely different way to skin the fish:

variable1 = 3 - variable1;

should toggle nicely between 1 and 2 (;.
Wow! That's nifty.
__________________
And the WORD was made flesh, and dwelt among us. (John 1:14)
Reply With Quote
  #8   (View Single Post)  
Old 20th November 2008
nfries88's Avatar
nfries88 nfries88 is offline
Port Guard
 
Join Date: Sep 2008
Posts: 24
Default

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.
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT. The time now is 07:56 AM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Content copyright © 2007-2010, the authors
Daemon image copyright ©1988, Marshall Kirk McKusick