7

So I know that C++ has an Operator Precedence and that

int x = ++i + i++;

is undefined because pre++ and post++ are at the same level and thus there is no way to tell which one will get calculated first. But what I was wondering is if

int i = 1/2/3;

is undefined. The reason I ask is because there are multiple ways to look at that (1/2)/3 OR 1/(2/3). My guess is that it is a undefined behavior but I would like to confirm it.

hmjd
  • 120,187
  • 20
  • 207
  • 252
Caesar
  • 9,483
  • 8
  • 40
  • 66
  • 3
    No, it's not undefined. It's (one divided by two) divided by three. It's an ordinary math expression, in other words. – Robert Harvey Jul 02 '12 at 15:41
  • I think your thinking is a little vague here about the first one and that bled into your thinking about the second one. The first really boils down to the order of argument evaluation for a function being undefined. That is, if you think about it as `operator+(++i,i++)` then it jumps right out at you. – Chris A. Jul 02 '12 at 15:47
  • 1
    C++ (and most other programming languages) have a defined order of precedence that is borrowed from mathematics. You do not look at an expression multiple ways; mathematical operations have a hierarchy. However you can change the order of an operation using (well placed) parenthesis. – Thomas Anthony Jul 02 '12 at 15:55
  • 5
    The undefinededness of `int x = ++i + i++` has nothing to do with operator precedence. – Benjamin Lindley Jul 02 '12 at 16:23
  • 2
    Note also that the undefined behavior has nothing to do with operator precedence. It has to do with order of execution, and whether or not `i` can be modified multiple times between a sequence point. As it happens, pre-increment and post-increment are *not* at the same precedence level. – Steve Jessop Jul 02 '12 at 16:32
  • Possible duplicate of [Order of commutative mathematical operations](https://stackoverflow.com/q/49506802/608639), [C/C++ Math Order of Operation](https://stackoverflow.com/q/11296854/608639), [What are the rules governing C++ single and double precision mixed calculations?](https://stackoverflow.com/q/4239770/608639), [Order of operations to maximize precision](https://stackoverflow.com/q/45524072/608639), etc. – jww Mar 27 '18 at 07:47

5 Answers5

17

If you look at the C++ operator precedence and associativity, you'll see that the division operator is Left-to-right associative, which means this will be evaluated as (1/2)/3, since:

Operators that are in the same cell (there may be several rows of operators listed in a cell) are evaluated with the same precedence, in the given direction. For example, the expression a=b=c is parsed as a=(b=c), and not as (a=b)=c because of right-to-left associativity.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
6

In your example the compiler is free to evaluate "1" "2" and "3" in any order it likes, and then apply the divisions left to right.

It's the same for the i++ + i++ example. It can evaluate the i++'s in any order and that's where the problem lies.

It's not that the function's precedence isn't defined, it's that the order of evaluation of its arguments is.

Étienne
  • 4,773
  • 2
  • 33
  • 58
jcoder
  • 29,554
  • 19
  • 87
  • 130
5

The first code snippet is undefined behaviour because variable i is being modified multiple times inbetween sequence points.

The second code snippet is defined behaviour and is equivalent to:

int i = (1 / 2) / 3;

as operator / has left-to-right associativity.

hmjd
  • 120,187
  • 20
  • 207
  • 252
  • can you explain further why first code snippet is undefined behavior? It gives the output 10 if you use `i = 4`. Sorry, am a novice. – akaHuman Jul 02 '12 at 15:52
2

It is defined, it goes from left to right:

#include <iostream>

using namespace std;

int main (int argc, char *argv[]) {
    int i = 16/2/2/2;
    cout<<i<<endl;
    return 0;
}

print "2" instead of 1 or 16.

madreblu
  • 373
  • 5
  • 15
0

It might be saying that it is undefined because you have chosen an int, which is the set of whole numbers. Try a double or float which include fractions.

Rash
  • 1