Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.
7954 Discussions

different result of Volatile variables between icc and vc

Xiaoming_D_Intel
Employee
346 Views

If defined a variable, we used key "volatile" as below:
volatile int i=5;
volatile has multiple meanings. To a compiler writer it means to take no code generation shortcuts when accessing such an object. "Volatile" is to reminder compiler to not suppose or guess some conditions when optimized, the variablecould be change by some unexpected elementsanytime.
so, the variable i should be stored in SRAM, every time we used it, we read it from SRAM.
let's see a simple case:
include
include
volatileint i=1, j=1;
i=(i++)+(j++)+2;
j=i=i++;
printf("i=%d,j=%d\n",i,j);

with ICC compiler, result is:
i=3,j=2(same result with gcc)

withVC compiler, result is
i=6,j=5

I thinks that i=(i++)+(j++)+2 was translated to:
ICC:
t=t+t1+2; (t is equal to 4)
t++; (t is equal to 1,then executet++, t is equalto 2)
t1++; (t1 is equal to 2)
Then, j=i=i++;
Outputis i=3,j=2
VC:
t=t+t1+2; (t is equal to 4)
t++; (t is equalto 5)
t1++; (t1 is equal to 2)
Then, j=i=i++;
Outputis i=6,j=5.
if did not use Volatile,we got same result(i=6,j=5) no matter which compiler used.
if integrated icc to VS2008, compiled both with VC and icc, we got different result.

0 Kudos
6 Replies
Om_S_Intel
Employee
346 Views

It looks a bug in gcc and icc.
0 Kudos
TimP
Honored Contributor III
346 Views

It looks a bug in gcc and icc.
gcc developers are notoriously uncaring about the results produced by source code with Undefined Behavior. Are you proposing that introduction of volatile makes the results defined according to VC? Microsoft has been known to change their own "standards."
0 Kudos
jimdempseyatthecove
Honored Contributor III
346 Views

i and j should both be 4

With volatile, the rhs expression should have been evaluated, including the ++, prior to the store (=).
i=(i++)+(j++)+2;
i=2 j=2
i=(1)+(1)+2;
i=4;
j=i=i++;
i=5
i=4
j=4

Without volatile, the compiler could optimize the (remove the) ++, and potentially equivilence i and j, and further reduce the arguments of the printf to constants (both 4).

It would appear that from your quoted results that the ++ operator is occuring after the store (=). (bug, because it is changing the results).

Jim
0 Kudos
Om_S_Intel
Employee
346 Views
I reviewed C++ standard. It is not a bug in icc and gcc.

The test uses language constructs that have undefined behaviour according to C/C++ standard:

>>> i=(i++)+(j++)+2;
>>> j=i=i++;

The value of i is being modified more than once between two sequence points. Refer to the rules for expressions (section 5, paragraph 4 of the ISO C++ standard):

"Except where noted, the order of evaluation of operands of
individual operators and subexpressions of individual
expressions, and the order in which side effects take place,
is unspecified. Between the previous and next sequence
point a scalar object shall have its stored value modified at
most once by the evaluation of an expression. Furthermore,
the prior value shall be accessed only to determine the value
to be stored. The requirements of this paragraph shall be met
for each allowable ordering of the subexpressions of a full
expression; otherwise the behavior is undefined.

[Example:
i = v[i++]; // the behavior is unspecified
i = 7, i++, i++; // i becomes 9
i = ++i + 1; // the behavior is unspecified
i = i + 1; // the value of i is incremented
-end example]"
0 Kudos
Om_S_Intel
Employee
346 Views

I craeted a knowlege base article using content of this thread http://software.intel.com/en-us/articles/different-result-of-volatile-variables-between-icc-and-vc/.
0 Kudos
jimdempseyatthecove
Honored Contributor III
346 Views


It is a shame that "=" was not included in the definition of sequence point.
I think this is a case where some strong vendors did not want to correct their compiler behavior to do the right thing.

i = i + 1;

Implicitly has a sequence point between the two sides of =.

i = v[i++];

Although undefined, should have a sequence point at = as this would remove ambiguities in the language.




0 Kudos
Reply