Bug 11751 - wrong evaluation order of an expression
Summary: wrong evaluation order of an expression
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 3.2
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
: 762 816 1039 1570 2550 2673 3165 3324 4978 5051 5159 5494 5516 5724 6409 6765 6790 6891 7135 8175 9334 9675 9693 10947 11363 12552 13403 14417 14951 15012 15103 16309 16887 17018 17095 17253 17282 17507 17639 19798 20181 21246 21404 22248 24015 26060 26418 26642 26730 26820 26923 27153 27233 27344 27646 30935 31398 32067 32133 32536 33043 33248 33270 37800 38516 39143 40366 42711 (view as bug list)
Depends on:
Blocks:
 
Reported: 2003-07-31 17:52 UTC by Elitsa Mladenova
Modified: 2017-06-19 16:19 UTC (History)
61 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Elitsa Mladenova 2003-07-31 17:52:02 UTC
bellow is simple code that express this bug:

/************
 * File : b.C
 ************/

#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 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 22 Giovanni Bajo 2004-09-02 13:00:51 UTC
Volker recently added a small paragraph about this very common non-bug to our 
non-bug page:

http://gcc.gnu.org/bugs.html#nonbugs_c

You can read here about 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:18: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. ***
Comment 87 Elizbath Martin 2014-04-09 05:51:00 UTC
For the good expansion order make a step by step working Like when go for the buying of the juicer/blender  http://zinch.zendesk.com/entries/31114770-Locating-Smoothie-Makers-In-Low-price customer feedback is the key of the success. So For the right order of the expansion an expert advice can work better for you.
Comment 88 Oleg 2017-06-16 21:22:22 UTC
Is this produces correct output?

#include <cstring>
#include <cstdio>

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 89 Oleg 2017-06-16 21:22:59 UTC
Is this produces correct output?

#include <cstring>
#include <cstdio>

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