Yuri Bittencourt
Yuri Bittencourt

Reputation: 121

Operator evaluation order in C, how exactly do they work?

I have several doubts about the order of evaluation of the operators, in this first example, both variable A and variable B can be executed first against this expression

#include <stdio.h>

int main(void)
{
    int A = 5, B = 3;
    int c = a + b;   // Can any of the variables be executed first, 
                     // depending on the compiler ?
    return 0;
}

In this example, it may have side effects if function g modifies variable A

#include <stdio.h>

int main(void)
{
    int A = 5, B = 3
    int c = f(A) + g(B);
    return 0;
}

Comparison operators, such as the > operator, don't have an order for their operands?

#include <stdio.h>

int main(void)
{
    int A = 5, B = 3
    int c = f(A) > g(B);
    return 0;
}

One more example now, using the operator ,

#include <stdio.h>

int main(void)
{
    int A = 5, B = 3
    int c = f(A, B);
    return 0;
}

In short, all these examples I gave, the order of evaluation, will it depend on the compiler?

Upvotes: 0

Views: 200

Answers (1)

Lundin
Lundin

Reputation: 213799

The formal (but quite unhelpful) definition is found in C17 6.5/3:

The grouping of operators and operands is indicated by the syntax. Except as specified later, side effects and value computations of subexpressions are unsequenced.

This single, crappy sentence is the very definition of operator precedence and order of evaluation both. We can and should go back to read C99 6.5/3 in order to find far more well-written, previously normative text:

Except as specified later (for the function-call (), &&, ||, ?:, and comma operators), the order of evaluation of subexpressions and the order in which side effects take place are both unspecified.

The meaning is the same though. Regarding order of evaluation, the "side effects and value computations of subexpressions are unsequenced" part of the current C standard means that for most operators with more than one operand (as well as function argument lists) the order of evaluation is unspecified behavior.

Which does indeed mean that the order depends on the compiler, may be undocumented and should not be relied upon. It even means that the same compiler is allowed to change the ordering on case to case basis in the same program! So given the code f(a) + f(b); f(a) + f(b);, it may even be executed as f(a) f(b) f(b) f(a) if the compiler likes to do so.

The only (non-unary) operators that have a well-defined order of evaluation are &&, ||, ?: and ,.

Upvotes: 4

Related Questions