Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can someone explain how this C snippet will be evaluated w.r.t sequence points?

Tags:

c

expression

Is this Undefined Behavior under C? I say this because I think that the function inc(int *k) can be thought of as an expression whose side effect is to update the value at the address of k. So, would that make it equivalent to i=i++, which is UB?

#include <stdio.h>
/*Edited(See comments below on dbush's answer)*/
int inc(int *k) {return ++(*k);}
/*End of edit*/
int main() 
{
  int i=0;
  int *ptr = &i;
  i = inc(ptr);
  printf("%d\n", i);
}
like image 346
abjoshi - Reinstate Monica Avatar asked Aug 23 '18 01:08

abjoshi - Reinstate Monica


People also ask

What are the sequence points in C?

The C language defines the following sequence points: Left operand of the logical-AND operator (&&). The left operand of the logical-AND operator is completely evaluated and all side effects complete before continuing. If the left operand evaluates to false (0), the other operand is not evaluated.

What is meant by sequence point?

A sequence point defines any point in a computer program's execution at which it is guaranteed that all side effects of previous evaluations will have been performed, and no side effects from subsequent evaluations have yet been performed.


1 Answers

The behavior is well defined because calling a function counts as a sequence point, and each statement within the function is also a sequence point. It is not the same as if the body of the function were put in its place.

First inc is called. This invokes a sequence point.

Within the function, the statement return ++(*k) is executed, which first evaluates the containing expression. This results in i in main getting incremented to 1, and the expression evaluates to the new value of i, which is 1. The return statement returns that value from the function, and the completion of that statement is another sequence point, so the side effect of incrementing i is guaranteed to be complete.

Back in main, the value of 1 returned from inc is then assigned to i.

Had you instead done this:

i = ++(*ptr);

That would be undefined behavior because there is no sequence point between assigning to i and the side effect of incrementing i via *ptr.

like image 66
dbush Avatar answered Sep 24 '22 19:09

dbush