Is the order of evaluation with comma operator & assignment in C predictable?
Asked Answered
S

1

6

Recently cppcheck raised an error in some C code, that has the structure:

((void)(value_prev = value), value = new_value())

In most cases this can be split onto 2 lines, however there are some cases this is useful to have in a single statement.

In practice I found this works with popular compilers (GCC/Clang/MSVC), which don't give any warnings (even with warning levels set to their highest).


Example code:

#include <stdio.h>

int get_next(int i);

int main() {
    int i = 0, i_prev = 10;
    do {
        printf("%d\n", i);
    } while ((void)(i_prev = i),
             (i = get_next(i)) != 10);
}

CppCheck 1.73 (latest at time of writing) gives an error with this code:

(error) Expression '(void)(i_prev=i),(i=get_next(i))!=10'
depends on order of evaluation of side effects`

While the code could be changed to quiet the warning, is the order really undefined?

Sixtynine answered 30/4, 2016 at 2:15 Comment(2)
Could it be that get_next(i) is a macro, like #define getnext(i) i++ ?Berchtesgaden
No, in this case its defined as a function, cppcheck gives the error on this code without any modifications.Sixtynine
C
9

The order is defined, because there is a sequence point between them. See ISO/IEC 9899 6.5.17:

The left operand of a comma operator is evaluated as a void expression; there is a sequence point after its evaluation. Then the right operand is evaluated; the result has its type and value. 95) If an attempt is made to modify the result of a comma operator or to access it after the next sequence point, the behavior is undefined.

They then give an explicit example:

In the function call
f(a, (t=3, t+2), c)
the function has three arguments, the second of which has the value 5.

I'm not entirely sure why CppCheck is flagging it.

Cali answered 30/4, 2016 at 2:31 Comment(1)
@Alex If it is, then C99 borrowed it from C++. I don't have any C specs earlier than C99 to compare.Cali

© 2022 - 2024 — McMap. All rights reserved.