This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

C Operator Associativity Issue in CCS 5.1.1

Other Parts Discussed in Thread: MSP430F247

I have an issue with operator associativity that looks like an unreported bug in CCS 5.1.1.  I am compiling a C program for an MSP430F247 processor.

I have two similar statements calling two functions and performing an "and" operation on the function results.

1) ret = (WriteBQAddr(0) & ReadBQ(rPtr));

This one executes as one would expect in the following order according to the associativity of the bit wise and: a) it calls WriteBQAddr first keeping the result locally, b) it then calls ReadBQ and returns a result, c) it performs the bit wise and d) assigns the result to the variable "ret".

2) ret += (WriteBQAddr(0) & ReadBQ(rPtr++));

This one does NOT correctly associate the function calls in the bit .wise and.  It executes as: a) it calls ReadBQ first (as it shouldn't) incrementing the pointer and saving the return locally, b) then calls WriteBQAddr, c) then does a bit wise "and" on the two results and d) then sums the result of the and into the variable "ret".

While there are workarounds for this, it seems as obvious disregard for the C operator associativity.  Does anyone else have this issue?

Neil

PS. if one removes the rPtr++ pointer increment in the second case, the problem remains.  Thus the += seems to confuse the compiler association code.

  • You are not talking about associativity, but rather about commutativity.  C does not guarantee that the left-hand operand of an operator is evaluated before the right-hand operand, except in a few special cases.  You need to rearrange your source code so that there is a sequence point between the two operations that you want performed in a particular order.  For example:

    ret = WriteBQAddr(0); ret &= ReadBQ(rPtr++);

  • Douglas,

    Thanks.  I pretty much assumed that answer, but I will say I am disappointed.  I consider evaluation order for operator arguments to be an essential feature of "C", so this sounds like a bug to me.  But maybe my memory for C89 isn't as good as I thought.

    Be that as it may, I have two follow up questions:

    1 - Is there a documented summary of (what I would call) non-"C"-conforming operations in the compiler that I can easily access?  Did I miss that section of the C++ Compiler UG (I have the one in slau132g.pdf - ver 4.1)?  If so, a little pointer to that info would help.  (Particularly with respect to variations in evaluation order for operator arguments ;) )

    2 - Is there a flag or flags which will enforce additional conformance on this issue that I can use?  Specifically, does the use of the KR or ANSI (or even GNU) enforcement flags in the compiler insure evaluation order based on operator associativity?

    Thanks again,

    Neil

  • The compiler adheres to the C standard's requirements for operator precedence, so there is no need for additional documentation.  See http://c-faq.com/expr/seqpoints.html.

    Only a handful of operators impose an ordering on the operands:

    • &&
    • ||
    • ?:
    • , (comma)

    There is no mode or switch in the compiler to enforce any particular order of operations for which the standard does not dictate an order.

  • No version of the C standard (all of which I contributed to) requires that the operands of most operators be evaluated in left-to-right order, and nearly all C compilers do evaluate them in the opposite order in some cases.  The same is true for arguments to a function.

    The only non-C89-conforming feature of TI's C6000 compiler that I can recall is that in COFF mode, uninitialized external objects are not default-{zero,null}-initialized.  (In EABI mode, they are.)  The work-around is to provide explicit initialization in your source code.

    There are several different "modes" for the compiler, including strict-ANSI and GNU-extensions.  There is not (as yet) a mode for full C99 or C11 conformance, but some of the C99 additions (including "restrict" qualification and <stdbool.h>) have been implemented in the current release of the compiler.

    There is no compiler option to cause it to enforce your notion of how C "should" operate, as opposed to how the standard guarantees that it will operate.

    I note again that it is not a matter of "associativity".  You can override the actual operator associativity by using parentheses, but the only way to enforce a particular order of evaluation is to make sure that there are sequence points where you want them.  Breaking an expression up into shorter expression statements is one way to obtain intermediate sequence points; the comma operator is another.