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?

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

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

Children