Advanced

Microsoft's C++ compiler has violated the ISO language standard for at least the last three versions

Posted by dave on · 5 comments
LXer; By Robert Whitinger
Mail this story
Print this story

...I think that Microsoft's C++ compiler has violated the ISO language standard at least for the last three versions, and they are now fixing the bug in their C# compiler. Think of all that MS code out there that is broken!

Submitted for discussion...

You will find this interesting.

Take this program:

#include "stdio.h"
int main()
{
  int a = 2;
  int b = 3;
  b++;
  a = b++ * a++;
  int c = a % b;
  printf("a = %d    b = %d    c = %d",a,b,c);
  return 0;
}

and compile it. Depending on where you compile, you get different results:

gcc:
a = 8   b = 5  c = 3

MS c++ Version 6, 7, and 8:
a = 9   b = 5  c = 4

MS c#:
a = 8   b = 5  c = 3

So, I think this says that Microsoft's c++ compiler has violated the iso language standard at least for the last three versions, and they are now fixing the bug in their c# compiler. Think of all that MS code out there that is broken!

  Nav
» Read more about: Story Type: News Story; Groups: GNU, Microsoft

» Get new stories by e-mail: nightly or as they are published

« Return to the newswire homepage

  Related stories
» More like this

Comments (5)

Just because compilers do something different does NOT mean that a standard has been violated. You need to cite WHERE in the standard it says something has to be done in a certain way. I don't have the ISO specs for C++, but I believe the construct a=...a++ is NOT defined, and thus, there IS NO VIOLATION. In the construct a=..a++..;, the post-increment happens sometime after the read of a, and before the statement is completed, but whether it happens before or after the assignment is, I believe, compiler-dependent. And intentionally so. It certainly varies in the real world, and has for a long time. Portable programs should NEVER use pre/post-increment and an assignment on the same variable in the same statement, and I believe that's really old advice. C# is a different language anyway. It's not at all unreasonable for C# to do one thing, and C++ to do something different. Having a C# example isn't convincing.
While I don't actually have the standard spec either, all of the sources that I've looked so far specify that the "++" operator has a higher precedence than the "=" operator.

MS C++ is wrong.
Please do us a favor and consult Google.

a = b++ * a++;

is undefined behavior. Meaning that you can't portably rely on the result of this expression. Operator precedence has nothing to do with it; the C and C++ standards require that a variable can only be modified once within an expression. Attempts to modify it more than once are undefined.

See: http://www.eskimo.com/~scs/C-faq/q3.1.html http://www.eskimo.com/~scs/C-faq/q3.2.html http://www.eskimo.com/~scs/C-faq/q3.8.html

Remember, for your code to work `i = i++` must be valid, which would make `a[i] = i++` valid, and both of those ARE NOT VALID.

C# is completely different, as the order of evaluation within an expression is fully defined.
The standard does NOT forbid multiple modifications in the same expression. It forbids multiple modifications to the same scalar value without an intervening sequence point between the modifications. A sequence point is introduced after each complete expression, but they are also introduced by function calls and the builtin comma, &&, and || operators, among some other mechanisms. (Read section 1.9 and chapter 5 in the standard.) Thus it is possible to have a single expression with multiple sequence points, and therefore possible to safely have multiple modifications to the same value in the same expression.

For example, even though there are 2 modifications to a, the comma operator makes the following expression valid and well-defined:

a = ++a, a + 1;

Chris
a = b++ * a++;

Is not defined by the C++ standard. You are invoking undefined behavior.

a = a++; alone is not defined.

In short the C++ language standard basically says that '=' is not a sequence point. All side effects must be complete before the next sequence point in the code but it doesn't specify when each side effect's evaluation has to happen during the evaluation of the previous expression.

As such the ONLY sequence point is the ';' and the incrementing of 'a' can happen before or after the assignment to 'a' .

assume the following:

a = 3;

a = a++;

Compiler 1 returns "4" for 'a'. Compiler 2 returns "3" for 'a'. Neither is incorrect but your code is not well formed.

Does that clear it up a bit? I'd steer clear of all postfix operators because people really don't know how to use them properly and their value is questionable to begin with.

Take the following:

std::vector::iterator it = string.begin();

for (; it != string.end(); it++) { //... code }

If you don't know why the above code is worse than:

for (l it != string.end(); ++it) { //... code }

then you probably shouldn't be using postfix ++ or --. Many C++ book authors choose to use i++ rather than ++i. I don't know why. I think it confuses people into thinking the wrong thing about for loops and side-effects in an expression are generally not well understood throughout the C++ and C communities.

Dave

Post a comment

A free account is needed to post. Write your comment here first: your text is kept in this browser while you sign up or log in, and is waiting for you when you come back.

Your message:
|||||
10
Markdown: **bold**, *italic*, [text](https://link), - lists, > quotes, $x^2$ for math. Formatting help

Sign up and post (it is free)  or  Log in and post