This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

never, ever increments

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?

  • 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.

  • 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.

  • "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...

  • 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.

  • "Maybe sBuf0tail = ((++sBuf0tail) % BUFFER_SZ);
    will work.
    ++X is not the same as X++ in all cases."

    It's undefined behaviour either way.