11751 – wrong evaluation order of an expression (original) (raw)

Description Elitsa Mladenova 2003-07-31 17:52:02 UTC

bellow is simple code that express this bug:

/************

#include <stdio.h>

int main() { int a = 1; printf(" a = %i \n",(a++)+(++a)); //4

    a = 1;
    printf(" a = %i \n",(a++)+(a++)+(++a));         //4

    return 0;
    }

After compilation in a following way:

c++ -o b b.C

The result was:

a = 4 a = 4

Comment 1 Andrew Pinski 2003-07-31 17:55:50 UTC

Not a bug in gcc but rather in your code. Read about sequence points and modifying variables between them.

Comment 2 Wolfgang Bangerth 2004-08-05 15:01:03 UTC

*** Bug 15012 has been marked as a duplicate of this bug. ***

Comment 3 Wolfgang Bangerth 2004-08-05 15:01:24 UTC

*** Bug 15103 has been marked as a duplicate of this bug. ***

Comment 4 Wolfgang Bangerth 2004-08-05 15:01:37 UTC

*** Bug 14417 has been marked as a duplicate of this bug. ***

Comment 5 Wolfgang Bangerth 2004-08-05 15:01:50 UTC

*** Bug 13403 has been marked as a duplicate of this bug. ***

Comment 6 Wolfgang Bangerth 2004-08-05 15:02:01 UTC

*** Bug 12552 has been marked as a duplicate of this bug. ***

Comment 7 Wolfgang Bangerth 2004-08-13 15:39:33 UTC

*** Bug 11363 has been marked as a duplicate of this bug. ***

Comment 8 Wolfgang Bangerth 2004-08-13 15:40:29 UTC

*** Bug 17018 has been marked as a duplicate of this bug. ***

Comment 9 Wolfgang Bangerth 2004-08-13 15:45:58 UTC

*** Bug 14951 has been marked as a duplicate of this bug. ***

Comment 10 Wolfgang Bangerth 2004-08-13 15:46:10 UTC

*** [Bug 16887](show%5Fbug.cgi?id=16887 "RESOLVED DUPLICATE - Bad assignment in "int i=1; i=i++;"") has been marked as a duplicate of this bug. ***

Comment 11 Wolfgang Bangerth 2004-08-13 16:03:13 UTC

*** Bug 816 has been marked as a duplicate of this bug. ***

Comment 12 Wolfgang Bangerth 2004-08-13 16:03:23 UTC

*** Bug 4978 has been marked as a duplicate of this bug. ***

Comment 13 Wolfgang Bangerth 2004-08-13 16:03:39 UTC

*** Bug 5724 has been marked as a duplicate of this bug. ***

Comment 14 Wolfgang Bangerth 2004-08-13 16:03:50 UTC

*** Bug 6790 has been marked as a duplicate of this bug. ***

Comment 15 Wolfgang Bangerth 2004-08-13 16:04:00 UTC

*** Bug 7135 has been marked as a duplicate of this bug. ***

Comment 16 Wolfgang Bangerth 2004-08-13 16:04:09 UTC

*** Bug 9693 has been marked as a duplicate of this bug. ***

Comment 17 Wolfgang Bangerth 2004-08-13 16:04:33 UTC

*** Bug 16309 has been marked as a duplicate of this bug. ***

Comment 18 Wolfgang Bangerth 2004-08-13 16:05:53 UTC

*** Bug 10947 has been marked as a duplicate of this bug. ***

Comment 19 Volker Reichelt 2004-08-19 08:01:11 UTC

*** Bug 17095 has been marked as a duplicate of this bug. ***

Comment 20 Wolfgang Bangerth 2004-08-31 20:46:31 UTC

*** Bug 17253 has been marked as a duplicate of this bug. ***

Comment 21 Andreas Schwab 2004-09-02 12:36:30 UTC

*** Bug 17282 has been marked as a duplicate of this bug. ***

Comment 23 Andrew Pinski 2004-09-03 05:23:38 UTC

*** Bug 17282 has been marked as a duplicate of this bug. ***

Comment 24 Volker Reichelt 2004-09-15 19:51:56 UTC

*** Bug 17507 has been marked as a duplicate of this bug. ***

Comment 25 Andrew Pinski 2004-09-23 20:54:50 UTC

*** Bug 17639 has been marked as a duplicate of this bug. ***

Comment 26 Paolo Carlini 2005-02-07 00:19:13 UTC

*** Bug 19798 has been marked as a duplicate of this bug. ***

Comment 27 Andrew Pinski 2005-02-23 20:26:18 UTC

*** Bug 20181 has been marked as a duplicate of this bug. ***

Comment 28 Dion Picco 2005-02-23 20:38:54 UTC

The point I was making with my example is that the native types (int, long, char, etc...) have different behaviour than a user-defined class with the operator++. If it is compiler dependent which way the expression is evaluated, why not at least make them both agree? GCC is also the only compiler out of the 5 that I've tested that exhibits this behaviour... all others unify the behaviour of native and user-defined operator++.

Comment 29 Andrew Pinski 2005-02-23 20:41:16 UTC

(In reply to comment #28) The code is undefined, which means we should be able to do system("rm -Rf /");, note we don't.

Comment 30 Dion Picco 2005-02-23 20:46:30 UTC

Here is a better clarification:

Case 1

int a = 0; int b = a++ + a++; printf("b = %d\n", b); // output is 0

Case 2

class A { int a_; public: A() : a_(0) {}

int operator++() { return a_++; } };

A a; int b = a++ + a++; printf("b = %d\n", b); // output is 1

This is a simple case that shows how the behaviour of the operator++ should be united.

I'm not sure what you mean by the system(...) call... I understand that the code is undefined (meaning its up to the compiler vendor to implement as they see fit). I think the most fitting way is to have the above two cases unified in behaviour... isn't one of the reasons that operators were added to C++ was to allow user-defined types to mimic the functionality and usability of the native C types?

Comment 31 Andrew Pinski 2005-02-23 20:51:18 UTC

(In reply to comment #30)

I'm not sure what you mean by the system(...) call... I understand that the code is undefined (meaning its up to the compiler vendor to implement as they see fit). I think the most fitting way is to have the above two cases unified in behaviour... isn't one of the reasons that operators were added to C++ was to allow user-defined types to mimic the functionality and usability of the native C types?

Undefined means that we can do anything. Which where the system call comes from. The point is that this undefined, there does not even have be a constancy in the behavior across optimization levels, types or anything else.

Comment 32 Dion Picco 2005-02-23 23:27:34 UTC

I won't press the issue further because I have other things more pressing ;)

But I think the decision to not change the behaviour here is wrong. I cannot create an Integer class that acts as an int due to the operator++. Just because it is undefined does not mean that we have to arbitrarily have to choose a method that adds no value over one that adds good value. Nearly all other compiler vendors have adopted this method since it has an element of common-sense in the face of an undefined process. I get the feeling that the only reason it isn't changed is simply because no-one wants to do it. If there is another reason, what is it?

Comment 33 Paul Schlie 2005-02-24 10:34:44 UTC

Although I can confidently say that I've been less than enthusiastic with some of GCC's standards interpretations; here GCC's results in each of the examples you cite are within the set of semantically consent values which should be expected to result from an unspecified evaluation and/or value assignment order. (Although do agree that GCC has no license to return any value other than those which would result from these ordering ambiguities).

(Although do believe that GCC should adopt an lr evaluation order; as expressions which are otherwise ambitious are useless, and those which are unaffected are insensitive to it; resulting in no harm, only benefit; and with a little luck may lead to the C/C++ committees coming to their senses in time.)

Comment 34 Andrew Pinski 2005-04-20 02:42:18 UTC

*** Bug 3165 has been marked as a duplicate of this bug. ***

Comment 35 Andrew Pinski 2005-04-20 02:47:33 UTC

*** Bug 1039 has been marked as a duplicate of this bug. ***

Comment 36 Andrew Pinski 2005-04-20 02:54:56 UTC

*** Bug 2550 has been marked as a duplicate of this bug. ***

Comment 37 Andrew Pinski 2005-04-20 02:55:29 UTC

*** Bug 3324 has been marked as a duplicate of this bug. ***

Comment 38 Andrew Pinski 2005-04-20 02:56:28 UTC

*** Bug 5159 has been marked as a duplicate of this bug. ***

Comment 39 Andrew Pinski 2005-04-20 02:57:24 UTC

*** Bug 5494 has been marked as a duplicate of this bug. ***

Comment 40 Andrew Pinski 2005-04-20 02:58:56 UTC

*** Bug 5516 has been marked as a duplicate of this bug. ***

Comment 41 Andrew Pinski 2005-04-20 02:59:41 UTC

*** Bug 6409 has been marked as a duplicate of this bug. ***

Comment 42 Andrew Pinski 2005-04-20 03:03:00 UTC

*** Bug 9334 has been marked as a duplicate of this bug. ***

Comment 43 Andrew Pinski 2005-04-20 03:05:58 UTC

*** Bug 9675 has been marked as a duplicate of this bug. ***

Comment 44 Andrew Pinski 2005-04-21 04:58:47 UTC

*** Bug 6409 has been marked as a duplicate of this bug. ***

Comment 45 Giovanni Bajo 2005-04-27 11:40:56 UTC

*** Bug 21246 has been marked as a duplicate of this bug. ***

Comment 46 Andrew Pinski 2005-05-05 18:12:16 UTC

*** Bug 21404 has been marked as a duplicate of this bug. ***

Comment 47 Andrew Pinski 2005-06-30 13:26:45 UTC

*** Bug 22248 has been marked as a duplicate of this bug. ***

Comment 48 Andrew Pinski 2005-06-30 13:37:54 UTC

*** Bug 22248 has been marked as a duplicate of this bug. ***

Comment 49 Andrew Pinski 2005-07-01 14:29:11 UTC

*** Bug 22248 has been marked as a duplicate of this bug. ***

Comment 50 Andrew Pinski 2005-09-22 17:07:06 UTC

*** Bug 24015 has been marked as a duplicate of this bug. ***

Comment 51 Andrew Pinski 2005-11-10 03:17:31 UTC

*** Bug 1570 has been marked as a duplicate of this bug. ***

Comment 52 Andrew Pinski 2005-11-10 03:17:55 UTC

*** Bug 762 has been marked as a duplicate of this bug. ***

Comment 53 Andrew Pinski 2005-11-10 03🔞37 UTC

*** Bug 5051 has been marked as a duplicate of this bug. ***

Comment 54 Andrew Pinski 2005-11-10 03:48:21 UTC

*** Bug 8175 has been marked as a duplicate of this bug. ***

Comment 55 Andrew Pinski 2005-11-10 03:49:06 UTC

*** Bug 6765 has been marked as a duplicate of this bug. ***

Comment 56 Andrew Pinski 2005-11-10 03:49:41 UTC

*** Bug 6891 has been marked as a duplicate of this bug. ***

Comment 57 Andrew Pinski 2005-12-12 20:23:55 UTC

*** Bug 2673 has been marked as a duplicate of this bug. ***

Comment 58 Andreas Schwab 2006-02-01 10:34:43 UTC

*** Bug 26060 has been marked as a duplicate of this bug. ***

Comment 59 Andrew Pinski 2006-02-22 14:04:55 UTC

*** Bug 26418 has been marked as a duplicate of this bug. ***

Comment 60 Andrew Pinski 2006-03-11 15:09:47 UTC

*** Bug 26642 has been marked as a duplicate of this bug. ***

Comment 61 Emil Obermayr 2006-03-11 16:10:38 UTC

referring to duplicate 26642:

The behavior changed between gcc3 and gcc4 and the comment is "there is no reason the result should not change"?

Sorry, but I think that's a really bad way to handle things. When a update changes behavior, there should be et least an appropriate warning.

And another comment says "look at the warning you got". If you'd read the warnings you would have seen it refers to that part of the code that didn't change its behavior. So a code that only uses the array-version (that behaves differently) wouldn't get the warning.

I really doubt that there is any good reason that simple variables and array variables should differ in the order their expressions are solved.

Please, think about it. At least give a warning at the right place!

Comment 62 Andrew Pinski 2006-03-11 16:14:20 UTC

(In reply to comment #61)

referring to duplicate 26642:

The behavior changed between gcc3 and gcc4 and the comment is "there is no reason the result should not change"?

Why this is undefined code :).

Comment 63 Daniel Berlin 2006-03-11 16:49:57 UTC

(In reply to comment #61)

referring to duplicate 26642:

The behavior changed between gcc3 and gcc4 and the comment is "there is no reason the result should not change"?

There is simply no guarantee at all that the behavior of this will or won't change. It's undefined code. It could change depending on the phase of the moon.

Sorry, but I think that's a really bad way to handle things. When a update changes behavior, there should be et least an appropriate warning.

Unfortunately, it is impossible to warn for every permuation of undefined code at compilation time. However, in general, if you write code whose semantics are undefined, you are going to get burned. This is just the way the ball bounces.

Comment 64 Andrew Pinski 2006-03-17 16:59:23 UTC

*** Bug 26730 has been marked as a duplicate of this bug. ***

Comment 65 Andrew Pinski 2006-03-23 06:30:09 UTC

*** Bug 26820 has been marked as a duplicate of this bug. ***

Comment 66 Andrew Pinski 2006-03-29 19:26:07 UTC

*** Bug 26923 has been marked as a duplicate of this bug. ***

Comment 67 Andrew Pinski 2006-04-14 02:31:59 UTC

*** Bug 27153 has been marked as a duplicate of this bug. ***

Comment 68 Andrew Pinski 2006-04-14 02:50:56 UTC

*** Bug 27153 has been marked as a duplicate of this bug. ***

Comment 69 Andrew Pinski 2006-04-14 16:54:07 UTC

*** Bug 27153 has been marked as a duplicate of this bug. ***

Comment 70 Andrew Pinski 2006-04-21 00:40:19 UTC

*** Bug 27233 has been marked as a duplicate of this bug. ***

Comment 71 Andrew Pinski 2006-04-28 00:00:09 UTC

*** Bug 27344 has been marked as a duplicate of this bug. ***

Comment 72 Andrew Pinski 2006-05-17 19:06:04 UTC

*** Bug 27646 has been marked as a duplicate of this bug. ***

Comment 73 Richard Biener 2007-02-23 15:36:11 UTC

*** Bug 30935 has been marked as a duplicate of this bug. ***

Comment 74 Richard Biener 2007-03-30 13:03:33 UTC

*** Bug 31398 has been marked as a duplicate of this bug. ***

Comment 75 Andrew Pinski 2007-05-24 16:21:25 UTC

*** Bug 32067 has been marked as a duplicate of this bug. ***

Comment 76 Andrew Pinski 2007-05-28 22:47:19 UTC

*** Bug 32133 has been marked as a duplicate of this bug. ***

Comment 77 Andreas Schwab 2007-06-28 16:54:52 UTC

*** Bug 32536 has been marked as a duplicate of this bug. ***

Comment 78 Gregor Jasny 2007-08-10 12:02:07 UTC

*** Bug 33043 has been marked as a duplicate of this bug. ***

Comment 79 Richard Biener 2007-08-30 12:33:49 UTC

*** Bug 33248 has been marked as a duplicate of this bug. ***

Comment 80 Andreas Schwab 2007-08-30 16:10:21 UTC

*** Bug 33248 has been marked as a duplicate of this bug. ***

Comment 81 Andrew Pinski 2007-08-31 16:09:10 UTC

*** Bug 33270 has been marked as a duplicate of this bug. ***

Comment 82 Paolo Carlini 2008-10-10 16:33:54 UTC

*** Bug 37800 has been marked as a duplicate of this bug. ***

Comment 83 Andreas Schwab 2008-12-13 18:26:07 UTC

*** Bug 38516 has been marked as a duplicate of this bug. ***

Comment 84 Andrew Pinski 2009-02-09 18:45:28 UTC

*** Bug 39143 has been marked as a duplicate of this bug. ***

Comment 85 Andreas Schwab 2009-06-07 09:04:07 UTC

*** Bug 40366 has been marked as a duplicate of this bug. ***

Comment 86 Andreas Schwab 2010-01-12 16:24:19 UTC

*** Bug 42711 has been marked as a duplicate of this bug. ***

Is this produces correct output?

#include #include

int main() { int i = 100; i = i++ + ++i; printf("i=%d\n", i);

i = 100; i = ++i + i++; printf("i=%d\n", i);

i = 100; i = i + i++; printf("i=%d\n", i); return 0; }

output:

i=202 i=203

Is this produces correct output?

#include #include

int main() { int i = 100; i = i++ + ++i; printf("i=%d\n", i);

i = 100; i = ++i + i++; printf("i=%d\n", i);

i = 100; i = i + i++; printf("i=%d\n", i); return 0; }

output:

i=202 i=203

Comment 90 Emil Obermayr 2017-06-19 16:19:59 UTC

Dear Oleg,

You have three printf, but only 2 outputs.

You don't tell us, what the right output should be, and why.

Your tests are highly dependent on the order of evaluation. So the only use is to detect exactly this order of evaluation. This order is highly dependent on versions and platforms and lots of settings and configurations, which you did not specify.

I'd say you should define your point more exactly.

Yours

nobs