sequence-points

C++11 without sequence point?

Wikipedia says that sequence points are deprecated in C++11. What does that mean? Does that mean that undefined behaviors due to sequence points has no effects?

Why I got "operation may be undefined" in Statement Expression in C++?

to describe the problem simply, please have a look at the code below:

int main()
{
    int a=123;
    ({if (a) a=0;});
    return 0;
}

I got this warning from [-Wsequence-point]

Line 4: warning: operation on 'a' may be undefined

my g++ version is 4.4.5

I'll appreciate whoever would explain this simple problem.

btw you could find my original program and original problem in #7 in this Chinese site (not necessary)

UPD1:

though to change the code into ({if(a) a=0; a;}) can avoid the warning, but I recognized that the real reason of the problem may not be The last thing in the compound statement should be an expression followed by a semicolon.

because the documentary also said If you use some other kind of statement last within the braces, the construct has type void, and thus effectively no value.

an example can show it:

int main()
{
    int a=123, b;
    ({;});
    ({if (a) b=0;});
    return 0;
}

and this code got no warnings! so I think the real reason is something about sequence point.

please help!

UPD2:

sorry to @AndyProwl for having unaccept his answer which was accepted before UPD1. following his advise I may ask a new question (UPD1 is a new question different from the original one). I'll accept his answer again because it surely avoids warnings anyhow.:)

If I decided to ask a new question, I'll update this question to add a link.

Bit-fields and sequence points

For an implementation that packs f0 and f1 into the same byte, is the program below defined?

struct S0 {
       unsigned f0:4;
       signed f1:4;
} l_62;

int main (void) {
       (l_62.f0 = 0) + (l_62.f1 = 0);
       return 0;
}

I am interested in the answer for C99 and for C11 if there is reason to think that it is different there.

In C99, all I found was 6.5:2:

Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. [...]

It is not clear for me what consequences this paragraph has on the program above.

Based on a large number of randomized tests, most compilers appear to generate code where the two assignments do not interfere.

Is this code well-defined?

This code is taken from a discussion going on here.

someInstance.Fun(++k).Gun(10).Sun(k).Tun();

Is this code well-defined? Is ++k in Fun() evaluated before k in Sun()?

What if k is user-defined type, not built-in type? And in what ways the above function calls order is different from this:

eat(++k);drink(10);sleep(k);

As far as I know, in both situations, there exists a sequence point after each function call. If so, then why can't the first case is also well-defined like the second one?

Section 1.9.17 of the C++ ISO standard says this about sequence points and function evaluation:

When calling a function (whether or not the function is inline), there is a sequence point after the evaluation of all function arguments (if any) which takes place before execution of any expressions or statements in the function body. There is also a sequence point after the copying of a returned value and before the execution of any expressions outside the function.

How do Prefix (++x) and Postfix (x++) operations work?

Can someone tell me how prefix / postfix operators really work? I've been looking online a lot but haven't found anything.

From what I can tell prefex first increments, then does the operation and then assigns.
Postfix would do the operation first, then assign and then increment.

But I'm having a bit of trouble with my code:

int x, y;
x = 1;
y = x + x++; // (After operation y = 2)(x=2)

However when I do:

y = x++ + x; // (After operation y = 3)(x=2)

I'm not sure why these operations would be any different. I have two questions:

  • Could you explain the difference?

  • How does this apply to the other operator Prefix?

Is the `this` argument evaluated before or after other member function arguments?

In the following code a member function set() is called on a model, which is a null pointer. This would be undefined behavior. However, the parameter of the member function is a result of another function call that checks whether the model is a null pointer and throws in that case. Is it guaranteed that estimate() will always be called before the model is accessed or is it still Undefined Behaviour (UB)?

#include <iostream>
#include <memory>
#include <vector>


struct Model
{
    void set(int x)
    {
        v.resize(x);
    }

    std::vector<double> v;
};


int estimate(std::shared_ptr<Model> m)
{
    return m ? 3 : throw std::runtime_error("Model is not set");
}

int main()
{
    try
    {
        std::shared_ptr<Model> model; // null pointer here
        model->set(estimate(model));
    }
    catch (const std::runtime_error& e)
    {
        std::cout << e.what();
    }

    return 0;
}
Is the comma in a variable list a sequence point?

In the following type of code is there a sequence point between each variable construction, or is the result undefined?

int a = 0;
int b = a++, c = a++;

I wasn't able to find in the standard a specific reference to a sequence point here. Does that mean it is undefined, or just that I failed in my search? The completion of an expression is a sequence point, but does the above initialization also count?

Does int a=1, b=a++; invoke undefined behavior?

Does int a=1, b=a++; invoke undefined behavior? There is no sequence point intervening between the initialization of a and its access and modification in the initializer for b, but as far as I can tell, initialization is not "modification" of the object; an initializer is specified to give the "initial value" of the object. Per 6.7.8 Initialization, paragraph 8:

An initializer specifies the initial value stored in an object.

and it seems reasonable to take "initial" as being sequenced before any access to the object. Has this issue been considered before, and is there an accepted interpretation?

Is value of x*f(x) unspecified if f modifies x?

I've looked at a bunch of questions regarding sequence points, and haven't been able to figure out if the order of evaluation for x*f(x) is guaranteed if f modifies x, and is this different for f(x)*x.

Consider this code:

#include <iostream>

int fx(int &x) {
  x = x + 1;
  return x;
}

int f1(int &x) {
  return fx(x)*x; // Line A
}

int f2(int &x) {
  return x*fx(x); // Line B
}

int main(void) {
  int a = 6, b = 6;
  std::cout << f1(a) << " " << f2(b) << std::endl;
}

This prints 49 42 on g++ 4.8.4 (Ubuntu 14.04).

I'm wondering whether this is guaranteed behavior or unspecified.

Specifically, in this program, fx gets called twice, with x=6 both times, and returns 7 both times. The difference is that Line A computes 7*7 (taking the value of x after fx returns) while Line B computes 6*7 (taking the value of x before fx returns).

Is this guaranteed behavior? If yes, what part of the standard specifies this?

Also: If I change all the functions to use int *x instead of int &x and make corresponding changes to places they're called from, I get C code which has the same issues. Is the answer any different for C?

What should the result be when assigning a variable to a reference to itself, in-between modified and then returned by a function call?
#include <iostream>

int& addOne(int& x)
{
    x += 1;
    return x;
}

int main()
{
    int x {5};
    addOne(x) = x;
    std::cout << x << ' ' << addOne(x);
}

I'm currently in the middle of learning about lvalues and rvalues and was experimenting a bit, and made this which seems to be getting conflicting results. https://godbolt.org/z/KqsGz3Toe produces an out put of "5 6", as does Clion and Visual Studio, however https://www.onlinegdb.com/49mUC7x8U produces a result of "6 7"

I would think that because addOne is calling x as a reference, it would explicitly change the value of x to 6 despite being called as an lvalue. What should the correct result be?

Undefined behavior and sequence points reloaded

Consider this topic a sequel of the following topic:

Previous installment
Undefined behavior and sequence points

Let's revisit this funny and convoluted expression (the italicized phrases are taken from the above topic *smile* ):

i += ++i;

We say this invokes undefined-behavior. I presume that when say this, we implicitly assume that type of i is one of the built-in types.

What if the type of i is a user-defined type? Say its type is Index which is defined later in this post (see below). Would it still invoke undefined-behavior?

If yes, why? Is it not equivalent to writing i.operator+=(i.operator++()); or even syntactically simpler i.add(i.inc());? Or, do they too invoke undefined-behavior?

If no, why not? After all, the object i gets modified twice between consecutive sequence points. Please recall the rule of thumb: an expression can modify an object's value only once between consecutive "sequence points. And if i += ++i is an expression, then it must invoke undefined-behavior. If so, then its equivalents i.operator+=(i.operator++()); and i.add(i.inc()); must also invoke undefined-behavior which seems to be untrue! (as far as I understand)

Or, i += ++i is not an expression to begin with? If so, then what is it and what is the definition of expression?

If it's an expression, and at the same time, its behavior is also well-defined, then it implies that the number of sequence points associated with an expression somehow depends on the type of operands involved in the expression. Am I correct (even partly)?


By the way, how about this expression?

//Consider two cases:
//1. If a is an array of a built-in type
//2. If a is user-defined type which overloads the subscript operator!

a[++i] = i; //Taken from the previous topic. But here type of `i` is Index.

You must consider this too in your response (if you know its behavior for sure). :-)


Is

++++++i;

well-defined in C++03? After all, this is this,

((i.operator++()).operator++()).operator++();

class Index
{
    int state;

    public:
        Index(int s) : state(s) {}
        Index& operator++()
        {
            state++;
            return *this;
        }
        Index& operator+=(const Index & index)
        {
            state+= index.state;
            return *this;
        }
        operator int()
        {
            return state;
        }
        Index & add(const Index & index)
        {
            state += index.state;
            return *this;
        }
        Index & inc()
        {
            state++;
            return *this;
        }
};
Does *&++i cause undefined behaviour in C++03?

In another answer it was stated that prior to C++11, where i is an int, then use of the expression:

*&++i

caused undefined behaviour. Is this true?

On the other answer there was a little discussion in comments but it seems unconvincing.

Why is a = (a+b) - (b=a) a bad choice for swapping two integers?

I stumbled into this code for swapping two integers without using a temporary variable or the use of bitwise operators.

int main(){

    int a=2,b=3;
    printf("a=%d,b=%d",a,b);
    a=(a+b)-(b=a);
    printf("\na=%d,b=%d",a,b);
    return 0;
}

But I think this code has undefined behavior in the swap statement a = (a+b) - (b=a); as it does not contain any sequence points to determine the order of evaluation.

My question is: Is this an acceptable solution to swap two integers?

Does the statement `int val = (++i > ++j) ? ++i : ++j;` invoke undefined behavior?

Given the following program:

#include <stdio.h>
int main(void)
{
    int i = 1, j = 2;
    int val = (++i > ++j) ? ++i : ++j;
    printf("%d\n", val); // prints 4
    return 0;
}

The initialization of val seems like it could be hiding some undefined behavior, but I don't see any point at which an object is either modified more than once or modified and used without a sequence point in between. Could someone either correct or corroborate me on this?

Sequence points and side effects: Quiet change in C11?

C99 §6.5 Expressions

(1) An expression is a sequence of operators and operands that specifies computation of a value, or that designates an object or a function, or that generates side effects, or that performs a combination thereof.

(2) Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression.72) Furthermore, the prior value shall be read only to determine the value to be stored.73)

with the footnotes

72) A floating-point status flag is not an object and can be set more than once within an expression.

73) This paragraph renders undefined statement expressions such as

    i = ++i + 1;
    a[i++] = i;

while allowing

    i = i + 1;
    a[i] = i;

where C11 §6.5 changed to (the text of (1) has an addendum):

(1) […] The value computations of the operands of an operator are sequenced before the value computation of the result of the operator.

(2) If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. If there are multiple allowable orderings of the subexpressions of an expression, the behavior is undefined if such an unsequenced side effect occurs in any of the orderings.84)

where footnote 84 in C11 is the same as 73 in C99.

I'm a little confused… I read C11 (2) as "[…] either (a different side effect on the same scalar object) or (a value computation using the value of the same scalar object) […]" which seems to not even allow foo = ++i (there is a side effect and we use a value depending on the changed object). I'm not a native speaker, though, so it would be nice if one could tell me how this sentence should be "parsed". I understand C99, but I don't quite understand the wording of C11.

Anyway, the actual question: Is this a change from C99 to C11, or are these wordings equivalent? And if so, why it has been changed? And if not, could someone give an example of an expression which is UB in C99 but not in C11 or vice versa?

Why does the expression a = a + b - ( b = a ) give a sequence point warning in c++?

Following is the test code:

int main()
{
    int a = 3;
    int b = 4;
    a = a + b - (b = a); 

    cout << "a :" << a << " " << "b :" << b << "\n";    
    return 0;
}

Compiling this gives the following warning:

> $ g++ -Wall -o test test.cpp test.cpp: In function ‘int main()’:
> test.cpp:11:21: warning: operation on ‘b’ may be undefined
> [-Wsequence-point]

Why can the operation be undefined?

According to my understanding, first the subexpression (b = a) should be evaluated because of higher precedence of (), thus setting b = a. Then, since '+' and '-' have same precedence, the expression would be evaluated left-associatively. Thus, a + b should be evaluated next, and finally the result of (b = a) should be subtracted from a + b. I can't see any sequence-point rule being violated here.

Undefined behavior and sequence points

What are "sequence points"?

What is the relation between undefined behaviour and sequence points?

I often use funny and convoluted expressions like a[++i] = i;, to make myself feel better. Why should I stop using them?

If you've read this, be sure to visit the follow-up question Undefined behavior and sequence points reloaded.

(Note: This is meant to be an entry to Stack Overflow's C++ FAQ. If you want to critique the idea of providing an FAQ in this form, then the posting on meta that started all this would be the place to do that. Answers to that question are monitored in the C++ chatroom, where the FAQ idea started out in the first place, so your answer is very likely to get read by those who came up with the idea.) Are there sequence points in the expression a^=b^=a^=b, or is it undefined?

The allegedly "clever" (but actually inefficient) way of swapping two integer variables, instead of using temporary storage, often involves this line:

int a = 10;
int b = 42;

a ^= b ^= a ^= b; /*Here*/

printf("a=%d, b=%d\n", a, b); 

But I'm wondering, compound assignment operators like ^= are not sequence points, are they? Does this mean it's actually undefined behavior?

Shift operands sequenced in C++17

I read in the C++17 Standard $8.5.7.4:

The expression E1 is sequenced before the expression E2.

for shift operators.

Also cppreference rule 19 says:

In a shift operator expression E1<>E2, every value computation and side-effect of E1 is sequenced before every value computation and side effect of E2

But when I try to compile the following code with gcc 7.3.0 or clang 6.0.0

#include <iostream>
using namespace std;

int main() {
    int i = 5;
    cout << (i++ << i) << endl;
    return 0;
}

I get the following gcc warning:

../src/Cpp_shift.cpp: In function ‘int main()’:
../src/Cpp_shift.cpp:6:12: warning: operation on ‘i’ may be undefined [-Wsequence-point]
  cout << (i++ << i) << endl;
           ~^~

The clang warning is:

warning: unsequenced modification and access to 'i' [-Wunsequenced]

I used the following commands to compile:

g++ -std=c++17 ../src/Cpp_shift.cpp -o Cpp_shift -Wall
clang++ -std=c++17 ../src/Cpp_shift.cpp -o Cpp_shift -Wall

I get the expected 320 as output in both cases ( 5 * 2 ^ 6 )

Can someone explain why I get this warning? Did I overlook something? I also read this related question, but it does not answer my question.

edit: all other variants ++i << i, i << ++i and i << i++ result in the same warning.

edit2: (i << ++i) results in 320 for clang (correct) and 384 for gcc (incorrect). It seems that gcc gives a wrong result if the ++ is at E2, (i << i++) also gives a wrong result.

Unsequenced value computations (a.k.a sequence points)

Sorry for opening this topic again, but thinking about this topic itself has started giving me an Undefined Behavior. Want to move into the zone of well-defined behavior.

Given

int i = 0;
int v[10];
i = ++i;     //Expr1
i = i++;     //Expr2
++ ++i;      //Expr3
i = v[i++];  //Expr4

I think of the above expressions (in that order) as

operator=(i, operator++(i))    ; //Expr1 equivalent
operator=(i, operator++(i, 0)) ; //Expr2 equivalent
operator++(operator++(i))      ; //Expr3 equivalent
operator=(i, operator[](operator++(i, 0)); //Expr4 equivalent

Now coming to behaviors here are the important quotes from C++ 0x.

$1.9/12- "Evaluation of an expression (or a sub-expression) in general includes both value computations (including determining the identity of an object for lvalue evaluation and fetchinga value previously assigned to an object for rvalue evaluation) and initiation of side effects."

$1.9/15- "If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined."

[ Note: Value computations and side effects associated with different argument expressions are unsequenced. —end note ]

$3.9/9- "Arithmetic types (3.9.1), enumeration types, pointer types, pointer to member types (3.9.2), std::nullptr_t, and cv-qualified versions of these types (3.9.3) are collectively called scalar types."

  • In Expr1, the evaluation of the expression i (first argument), is unsequenced with respect to the evaluation of the expession operator++(i) (which has a side effect).

    Hence Expr1 has undefined behavior.

  • In Expr2, the evaluation of the expression i (first argument), is unsequenced with respect to the evaluation of the expession operator++(i, 0) (which has a side effect)'.

    Hence Expr2 has undefined behavior.

  • In Expr3, the evaluation of the lone argument operator++(i) is required to be complete before the outer operator++ is called.

    Hence Expr3 has well defined behavior.

  • In Expr4, the evaluation of the expression i (first argument) is unsequenced with respect to the evaluation of the operator[](operator++(i, 0) (which has a side effect).

    Hence Expr4 has undefined behavior.

Is this understanding correct?


P.S. The method of analyzing the expressions as in OP is not correct. This is because, as @Potatoswatter, notes - "clause 13.6 does not apply. See the disclaimer in 13.6/1, "These candidate functions participate in the operator overload resolution process as described in 13.3.1.2 and are used for no other purpose." They are just dummy declarations; no function-call semantics exist with respect to built-in operators."

Order of evaluation in v != std::exchange(v, predecessor(v))

I keep finding more idioms that lend themselves to std::exchange.

Today I found myself writing this in an answer:

do {
    path.push_front(v);
} while (v != std::exchange(v, pmap[v]));

I like it a lot more than, say

do {
    path.push_front(v);
    if (v == pmap[v])
        break;
    v= pmap[v];
} while (true);

Hopefully for obvious reasons.

However, I'm not big on standardese and I can't help but worry that lhs != rhs doesn't guarantee that the right-hand side expression isn't fully evaluated before the left-hand-side. That would make it a tautologous comparison - which would by definition return true.

The code, however, does run correctly, apparently evaluating lhs first.

Does anyone know

  • whether the standard guarantees this evaluation order
  • if it has changed in recent standards, which standard version first specified it?

PS. I realize that this is a special case of f(a,b) where f is operator!=. I've tried to answer my own query using the information found here but have failed to reach a conclusion to date:

Any good reason why assignment operator isn't a sequence point?

Is there any good reason for operator = not being a sequence point? Both in C and C++.

I have trouble thinking about an counter-example.

is i=f(); defined when f modifies i?

Related question: Any good reason why assignment operator isn't a sequence point?

From the comp.lang.c FAQ I would infer that the program below is undefined. Strangely, it only mentions the call to f as a sequence point, between the computation of the arguments and the transfer of control to f. The transfer of control from f back to the calling expression is not listed as a sequence point.

int f(void) { i++; return 42; }
i = f();

Is it really undefined?

As an end-note that I add to many of my questions, I am interested in this in the context of static analysis. I am not writing this myself, I just want to know if I should warn about it in programs written by others.

In C99, is f()+g() undefined or merely unspecified?

I used to think that in C99, even if the side-effects of functions f and g interfered, and although the expression f() + g() does not contain a sequence point, f and g would contain some, so the behavior would be unspecified: either f() would be called before g(), or g() before f().

I am no longer so sure. What if the compiler inlines the functions (which the compiler may decide to do even if the functions are not declared inline) and then reorders instructions? May one get a result different of the above two? In other words, is this undefined behavior?

This is not because I intend to write this kind of thing, this is to choose the best label for such a statement in a static analyzer.

Is moving twice in a single full expression allowed

Assume one has a function with the following prototype

template<typename T>    
std::unique_ptr<T> process_object(std::unique_ptr<T> ptr);

The function may return (a moved version of) the object that was passed to it, or a completely different object.

Is it legal C++ to use this function as follows?

std::unique_ptr<Widget> pw(new Widget());

pw = process_object(std::move(pw));

If I remember correctly, there is a C/C++ rule that forbids modifying an object more than once in a single full expression. Does this rule apply here? If yes, is there some way to express this idiom differently in a single line?

What if one replaces std::unique_ptr by the despised std::auto_ptr?

Is there a sequence point between a function call returning an object and a method call on that object?

If I write f(x)->g(args, ...) can I rely on a sequence point after f(x) before the evaluation of args, ...? I can see arguments both ways:

  • §1.9.17 "When calling a function (whether or not the function is inline), there is a sequence point after the evaluation of all function arguments (if any) which takes place before execution of any expressions or statements in the function body. There is also a sequence point after the copying of a returned value and before the execution of any expressions outside the function."
  • On the other hand, the object pointer is implicitly a hidden argument this as if I'd written g(f(x), args, ...) which suggests it's like an argument, and thus unspecified.

The -> operator is not a normal binary operator, since clearly g(...) cannot be evaluated before f(x) like it could if I wrote f(x) + g(...). I'm surprised I can't find some specific statement about it.

Is there a sequence point between these assignments?

Is there a sequence point between the two assignments in the following code:

f(f(x=1,1),x=2);
Behaviour of arr[i] = i++ and i = i + 1 statements in C and C++

In the C and C++ languages, the arr[i] = i++; statement invokes undefined behavior. Why does the statement i = i + 1; not invoke undefined behavior?

Why are these constructs using pre and post-increment undefined behavior?
#include <stdio.h>

int main(void)
{
   int i = 0;
   i = i++ + ++i;
   printf("%d\n", i); // 3

   i = 1;
   i = (i++);
   printf("%d\n", i); // 2 Should be 1, no ?

   volatile int u = 0;
   u = u++ + ++u;
   printf("%d\n", u); // 1

   u = 1;
   u = (u++);
   printf("%d\n", u); // 2 Should also be one, no ?

   register int v = 0;
   v = v++ + ++v;
   printf("%d\n", v); // 3 (Should be the same as u ?)

   int w = 0;
   printf("%d %d\n", ++w, w); // shouldn't this print 1 1

   int x[2] = { 5, 8 }, y = 0;
   x[y] = y ++;
   printf("%d %d\n", x[0], x[1]); // shouldn't this print 0 8? or 5 0?
}
sequence points in c

A sequence point in imperative programming 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.

What does this mean? Can somebody please explain it in simple words?

sequence-points