evaluation order - C

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

suppose I have two volatile variables, a and b.
And a simple statement:

c=a-b;

Which variable will be read first? I'm convinced, but can't find it written, that it's undefined, and thus

a=TCNT1-TCNT1;

is undefined. Likewise a construct like

if (safe && (value>3)) {..} 

where value and safe are volatile, and 'safe' is used to indicate validity of 'value', one can get a race condition where the main app reads value first, the interrupt fires and updates value and safe, and the main app then checks safe and uses the old, leftover value.

What do the C lawyers say?

/Kasper

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You might want to ask on the comp.lang.c newsgroup.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Good idea. Done.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The first case is unspecified and comes under the following clause:

ANSI C99 - Draft (May 2) wrote:

6.5 Expressions
Paragraph 3:
- The grouping of operators and operands is indicated by syntax. Except as specified later (for the function-call (), &&, ||, ?:, and comma operators), the order of evaluation of subexpressions and the order in which side effects take place are both unspecified.

The second case, however, is defined under the short-circuit evaluation rules.

ANSI C99 - Draft (May 2) wrote:

6.5.13 Logical AND operator
Paragraph 4:
- Unlike the bitwise binary & operator the && operator guarantees left-to-right evaluation; there is a sequence point after the evaluation of the first operand. If the first operand compares to 0, the second operand is not evaluated.

Similar language is used for the logical OR operator, except that if the first operand evaluates to true, the second is not evaluated.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

Last Edited: Fri. Jan 23, 2009 - 07:17 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I'm convinced, but can't find it written, that it's undefined
This is my vote.

In (an older edition of) K&R it talks about expression evaluation:

Quote:
The precedence and associativity of all the expression operators is summarized in the grammar.

Otherwise the order of evaluation of expressions is undefined. In particular the compiler considers itself free to compute subexpressions in the order it believes most efficient, even if the subexpressions involve side effects. The order in which side effects take place is unspecified.


But why not just code it so these questions don't come up?

Lightning fast glitch steals my thunder! And he has newer source materials. Curses!

Chuck Baird

"I wish I were dumber so I could be more certain about my opinions. It looks fun." -- Scott Adams

http://www.cbaird.org

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In the second, Glitch is correct, but you still have a problem. You can have safe read, the ISR happen, and then value read. So now you have the old value of safe and the new value of value. And if safe or value are more than one byte, the ISR can happen during the middle of the read, corrupting the value completely. In any situations where any of these things might occur, you should surround the statement with cli()/sei().

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

zbaird wrote:
Lightning fast glitch steals my thunder! And he has newer source materials. Curses!

LOL... I hope you're not cursing me... I have enough bad.hex's floating around here already ;)

Koshchi wrote:
In the second, Glitch is correct, but you still have a problem.

Hey I said it had a defined order... never said it was safe... hehehe

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you very much!

This came up while hunting for occasional misbehaviour in an existing piece of code, and that 'if' looked mighty suspicious.
I did not create it, I wouldn't create code that depended on this level of knowledge, and if I did for a good reason, I'd put in a comment explaining it.
It's perfectly safe then, as the interrupt disables itself after having done its job.

Thanks again.

/Kasper

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
In any situations where any of these things might occur, you should surround the statement with cli()/sei().

Does the compiler provide a sort of directive in order to include by it self these cli() sei() when reading multi-byte variables ?
George.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

angelu wrote:
Quote:
In any situations where any of these things might occur, you should surround the statement with cli()/sei().

Does the compiler provide a sort of directive in order to include by it self these cli() sei() when reading multi-byte variables ?
George.

no. In 8 bit microprocessors, it often takes more than one instruction to fetch or store a multibyte variable. The same can occur on a 16 bit processor doing multiple instructions on a 32 or 64 bit datum.

The need for this mechanism is rare; normally only for a variable that is accessed by both an interrupt service routine and non-interrupt code. Or in some RTOS situations.

More commonly, exclusion via cli() and sei() is not needed.