Fred,

That is true, Order of expression is undefined between execution points that is why the following statement can produce different results on different compilers:

A = 1;
F = A++ * A++;

Without the use of parenthesis the is no way for the user to know beforehand what the value of F will be.  The only guarantee is that when the before the next instruction is executed the all postfix operators will be evaluated prior to the start of the next C statement.

As a general rule rvalue expressions are calculated by the pre-compiler and not the compiler.  So the line:

ulDays  = ulSeconds / ( 60 * 60 * 24 );

Would be converted by the precompiler to:

ulDay = ulSeconds / 86400;

The calculation of the lvalue ulSeconds / 86400 will be handled at run time.

However, if ulSeconds is defined as a const it is possible that a smart precompiler will do the entire calculation and only the assignment will be done at runtime.

It is possible that the volatile keyword might cause the order of expression to be altered.

uint32_t * volatile ulpDMAAddress = 0xffff0000;  // Note this is a volatile pointer and NOT a pointer to volatile data.
uint32_t *ulpMyPointer;

ulpMyPointer = *ulpDMAAddress++ + *ulpDMAAddress++;

My mind is getting numb just looking at that code.  Suffice it to say that using multiple prefix/postfix operations in a single execution point is heavily deprecated because the actual results are implementation defined and my even be different depending upon what other math surrounds it.

Another implementation specific feature of C is the order of bits in bit fields.  They can be assigned from most significant to least significant or vice-versa.  It is totally up to the compiler.

As Allan Holub says C and  C++, in his book of the same name, gives the programmer "Enough Rope To Shoot Yourself in the Foot"




On 8/15/2024 6:45 PM, Fred Cisin via cctalk wrote:
It is not the hardware that is at fault.
If anybody else is to blame, it is the compiler.

On Thu, 15 Aug 2024, Paul Koning wrote:
More likely the language designers, assuming the compiler doesn't have a standards violation in its code.  In the case of C, the type promotion rules that were just explained are rather bizarre and surprising.  Other languages do it differently, with perhaps fewer surprises.  Some define it very carefully (ALGOL 68 comes to mind), some not so much.

C very explicitly leaves some thing undefined, supposedly to work with more machines, and Kernighan & Ritchie say that it is the responsibility of the programmer to create unambiguous code. for example, evaluation of expressions in the lvalue might be done before OR after evaluation of expressions in th rvalue

Some other languages are much stricter on types, etc. and have fewer ambiguities.

Reply via email to