Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the rationale for this undefined behavior?

Warning[...]: undefined behavior: the order of volatile accesses is undefined in this statement x.cpp xxx

Why this line is undefined behavior?

  case 2:
    Vdda = 3.3 * (*VREFINT_CAL) / ADC_DR->DATA;

Where the declarations/initializations are:

volatile short const *VREFINT_CAL = (short *) 0x1FFFF7BA;

and

volatile STRUCT_ADC_DR *ADC_DR = (STRUCT_ADC_DR*) 0x40012440;

defined by:

typedef struct
{
  unsigned DATA         : 16;
  unsigned              : 16;
} STRUCT_ADC_DR;

Is it because the compiler isn't sure about the volatile elements could act diferent in the order they get accessed? (What is the case)

But shouldn't it be ensured that the calculation gets performed from left to right as the operators have the same priority?

like image 809
dhein Avatar asked Jul 07 '15 12:07

dhein


People also ask

What causes undefined behavior?

In computer programming, undefined behavior (UB) is the result of executing a program whose behavior is prescribed to be unpredictable, in the language specification to which the computer code adheres.

Why does C have undefined Behaviour?

When we run a code, sometimes we see absurd results instead of expected output. So, in C/C++ programming, undefined behavior means when the program fails to compile, or it may execute incorrectly, either crashes or generates incorrect results, or when it may fortuitously do exactly what the programmer intended.

What does undefined mean programming?

In computing (particularly, in programming), undefined value is a condition where an expression does not have a correct value, although it is syntactically correct. An undefined value must not be confused with empty string, Boolean "false" or other "empty" (but defined) values.

What is the difference between unspecified and undefined?

Undefined Behavior results in unpredicted behavior of the entire program. But in unspecified behavior, the program makes choice at a particular junction and continue as usual like originally function executes.


1 Answers

volatile implies to the compiler that you are reading something that is not an ordinary memory address, like an I/O port. For two such reads, it is very likely that you will want those reads to happen in a certain order.

In both C and C++, the evaluation order of operands is not defined. If it helps you, think of the division as a function call:

Vdda = 3.3 * divide(*VREFINT_CAL, ADC_DR->DATA);

The point is now, that for volatile, where it's likely that the order is important, you might not want to leave this decision to the compiler. So it warns about it.

To get rid of the warning, simply make the order explicit by introducing additional sequence points to your code. For instance:

short const x = *VREFINT_CAL;
unsigned const y = ADC_DR->DATA;
Vdda = 3.3 * x / y;
like image 185
ComicSansMS Avatar answered Oct 27 '22 00:10

ComicSansMS