4

I ran into an "undefined behaviour" warning with IAR compiler for RL78 (v. 1.40.6) with the following code:

static volatile int x[2] = {1, 2};
int test(){
    return x[0]+x[1];
}

Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement C:\sandbox\test.c 32

The compiler tech note provides an explanation which boils down to two side effects (volatile accesses) being unsequenced.

However, I can see that the code above is no problem for newer compilers like GCC 8. Could someone point me to the change in the standard which makes accessing two volatile variables in a single statement legal?

Lundin
  • 195,001
  • 40
  • 254
  • 396
Dmitry Grigoryev
  • 3,156
  • 1
  • 25
  • 53
  • 1
    There is **no** undefined behavior here. But the order of the reads is unspecified. – curiousguy Dec 07 '18 at 04:15
  • 1
    [Can volatile variables be read multiple times between sequences points?](https://stackoverflow.com/questions/75247233/can-volatile-variables-be-read-multiple-times-between-sequences-points) You have tagged this question as C99 so there is no undefined behavior if compiling against that standard. In standard C (ISO 9899:2018) there is undefined behavior, however. Which is likely the reason you got a warning when you asked this question in 2018. – Lundin Jan 26 '23 at 15:24
  • @Lundin It seems that IAR compiler doesn't have a proper diagnostic for this in C99 mode, so it complains about "undefined behavior" even though there is none. – Dmitry Grigoryev Jan 30 '23 at 10:32
  • Yeah could be a false positive. Although it was of course still questionable code to do arithmetic on multiple volatile variables in the same expression, best practice is to make two temporary copies in RAM, to be explicit about when the value is read. (This was for example a MISRA C requirement even before C11.) – Lundin Jan 30 '23 at 11:02

2 Answers2

4

It is not illegal to access two volatile variables in the same statement but since the standard doesn't specify in which order the operands to the + operator are evaluated the language does not guarantee a specific ordering of the accesses, thus x[0] followed by x[1] and x[1] followed by x[0] are equally correct and the compiler may choose any of them. Since this may not be what the user expects, the IAR compiler issues a warning.

Johan
  • 3,667
  • 6
  • 20
  • 25
  • I understand that. My question was, why is this not a problem for GCC? – Dmitry Grigoryev Dec 07 '18 at 21:09
  • @DmitryGrigoryev your question doesn't make sense. There is no reason to be surprised when a compiler compiles correct code correctly – M.M Dec 10 '18 at 06:34
  • 3
    @DmitryGrigoryev It's not problem for the GCC compiler, like it's not problem for IAR compiler either. But it might be a problem for the *user*. IAR simply chooses warn the user about that, and GCC chooses not to. – user694733 Dec 10 '18 at 08:27
  • 1
    Why is it not illegal to access two volatile variables in the same statement? The access to a volatile variable is a side effect, and in the same statement those two accesses are unsequences. Two unsequenced side effects is undefined behavior. – KamilCuk Jan 26 '23 at 14:25
  • "It is not illegal to access two volatile variables in the same statement" It is explicitly undefined behavior, see [Can volatile variables be read multiple times between sequences points?](https://stackoverflow.com/questions/75247233/can-volatile-variables-be-read-multiple-times-between-sequences-points) Note the difference between C99 and C11 there. The reason IAR issues a warning is likely because the code was compiled as C11 (IAR got C11 support 2015:ish somewhere). – Lundin Jan 26 '23 at 15:22
  • 2
    @KamilCuk this question is tagged C99, where its unspecified but not undefined. So the answer is right in that context but given the warning the asker saw, they were probably actually compiling as C11 (or maybe IAR was giving a spurious warning, idk). – mbrig Jan 27 '23 at 06:12
  • @Lundin In this case, IMO the `volatile` objects are different. "If a side effect on a scalar object is unsequenced relative to either a different side effect on the **same** scalar object or a value computation using the value of the **same** scalar object, the behavior is undefined." – Andrew Henle Jan 30 '23 at 11:13
  • @AndrewHenle True, two array items are to be regarded as separate objects if they are accessed individually. – Lundin Jan 30 '23 at 11:33
1

Whether it is legal or not: Accessing a volatile variable could have side effects caused by something outside your code. For example reading x[i] might set all elements of x to the value i.

Now it depends on which one you read first, which is at least unspecified but might be undefined behaviour. Best to remove the unspecified behaviour. Assign x[0] and x[1] to two ints a return their some, and your unspecified behaviour is gone.

Why did one compiler not give a warning: Nobody forces it to.

gnasher729
  • 51,477
  • 5
  • 75
  • 98