3

Here's some simple code.

#include <iostream>
using namespace std;

bool func(char* m)
{
    *m = '4';
    return true;
}

using namespace std;
int main()
{
    char c1 = '3';
    cout  << "a" << c1 << func(&c1) << c1 << "b" << endl;

    return 0;
}

when compile this with g++ -O0 (4.7.2), output is a413b, for -O2, output is a414b. for clang++ 3.2, output is a314b.

Did I do anything undefined for c++ in this part of code?

Cœur
  • 37,241
  • 25
  • 195
  • 267
csslayer
  • 317
  • 2
  • 9
  • 1
    possible duplicate of [Undefined Behavior and Sequence Points](http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points) – chris Mar 05 '13 at 18:48
  • 4
    not a dupe of that. There are plenty of sequence points. – Flexo Mar 05 '13 at 18:52
  • It is generally a good idea to not mix computations and output. Compute all the values you need and then produce your output. – Bo Persson Mar 05 '13 at 18:58
  • @BoPersson Or do the output of different values in different statements. – James Kanze Mar 05 '13 at 19:47

2 Answers2

5

Yes, the order of evaluation of func(&c1) and the two c1 is unspecified.

This means that the three expressions can be evaluated in any order, resulting in any of the following outputs:

a313b
a314b
a413b
a414b

See function parameter evaluation order

Community
  • 1
  • 1
NPE
  • 486,780
  • 108
  • 951
  • 1,012
5

We'll shorten your example a bit to wrap our heads around it. Let's take the code:

char func(char* m) { *m = '4'; return *m; }

int main() {
    char c = '1';
    cout << c << func(&c);

}

The cout line gets transformed like this:

operator<<(operator<<(cout, c), func(&c))

Because function arguments can be evaluated in any order, the compiler can choose to evaluate the inner operator<<(cout, c) first, or func(&c) first. Depending on which one is evaulated first, you will either get:

`14`

or

`44`
Collin
  • 11,977
  • 2
  • 46
  • 60