a very, very odd thing.... #define BUFFER_SZ 64 unsigned char sBuf0tail; sBuf0tail = ((sBuf0tail + 1) % BUFFER_SZ); .. this increments a circular buffer index just fine. #define BUFFER_SZ 64 unsigned char sBuf0tail; sBuf0tail = ((sBuf0tail++) % BUFFER_SZ); .. this one never, ever increments. huh? is this some strange quirk of C I have never run into or is this a c51 compiler problem?
"Maybe sBuf0tail = ((++sBuf0tail) % BUFFER_SZ); will work. ++X is not the same as X++ in all cases." It's undefined behaviour either way.
Rather than just one reference, several from http://www.eskimo.com/~scs/C-faq/s3.html seem to apply here, so I'll link the whole lot. I know referencing FAQs is the lazy man's approach, so call me lazy.
"Advanced students can study the rules about 'sequence points' for extra credit." You could start by just putting "sequence point" into the search function on this forum - it's been discussed a number of times before...
Maybe sBuf0tail = ((++sBuf0tail) % BUFFER_SZ); will work. ++X is not the same as X++ in all cases. Look up pre / Post increment in your C book.
It's a strange quirk of C. The "++" operator is the post-increment operator. It means to use the value of the variable in an expression, and then increment it. In this case, the expression is (sbuf0Tail % BUFFER_SZ). Let's say sbuf0Tail is 0. The expression value is then (0 % 64), or 0. Remember that. Now increment sub0Tail to 1. Now finish the assignment statement: assign the remembered 0 to sbuf0Tail. You either want to pre-increment, or just write two separate statements to avoid confusion. I'd recommend the latter. Advanced students can study the rules about "sequence points" for extra credit. sBuf0Tail++; sBuf0Tail = sBuf0Tail % BUFFER_SZ; Incidentally, many (but not all) compilers are smart enough to strength-reduce that division to an & when the RHS is a power of 2. But division is expensive, and I don't think I've ever seen a compiler that avoids division when the RHS is not a power of two. I usually code this idiom as sBuf0Tail++; if (sBuf0Tail >= BUFFER_SZ) sBuf0Tail = 0; which on most architectures is almost as cheap as the AND, and much faster than division when you can't just AND.
View all questions in Keil forum