sergio masci wrote: > On Mon, 3 Aug 2009, Dave Tweed wrote: > > I've already written this up as part of the EQ quiz for Circuit Cellar > > #230 (September 2009), so you'll be able to read my solution there by > > the end of the month. In the meantime, give it some thought. It's > > actually quite straightforward. > > Now I'm curious :-) > > But I'll respect decission and I wont discuss it here. > > If I send you an offlist message (to your from address) will you > receive it or will your spam filter reject it as not coming from the > piclist? No, that address only accepts mail from the list server. To reach me offlist, substitute "dtweed" for "pic". > > In C, of course, you would simply write something like: > > > > tail = (tail + 1) % FIFO_SIZE; > > > > Or, if your compilier isn't smart enough to optimize the % operator: > > > > tail = (tail + 1 == FIFO_SIZE) ? 0 : tail + 1; > > > > Either of these is perfectly thread-safe; no standards-compliant compiler > > would turn either statement into multiple assignments to tail. > > Is this guarenteed anywhere? It's related to the concept of "sequence points" in C. In the C99 specification (Clause 6.5#2), it explicitly states: "Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression." Operator precedence also plays a role here: You can't modify the lvalue on the LHS of an assignment operator while evaluating the sub-expression on the RHS, and when you do evaluate the assignment, you may only modify the lvalue once. Therefore, the compiler may need to create an implicit temporary variable if you don't have an explicit one in the source code. > I can see: > > tail = (tail + 1) % FIFO_SIZE; > > being optimised to (if FIFO_SIZE is a power of 2): > > incf tail > movlw FIFO_SIZE-1 > andwf tail How about: incf tail, w andlw FIFO_SIZE-1 movwf tail > tail = (tail + 1 == FIFO_SIZE) ? 0 : tail + 1; > > being optimised to: > > incf tail > movf tail, w > xorlw FIFO_SIZE > btfss STATUS, Z > clrf tail How about: incf tail, w xorlw FIFO_SIZE btfss STATUS, Z xorlw FIFO_SIZE movwf tail In other words, there's no penalty for doing it right in these examples -- although to be honest, I doubt that a compiler would use the trick I used in the second one, unless it specifically recognized the source code idiom. More likely, it would create a full if-then-else structure with some extra gotos. -- Dave Tweed -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist