What is a sequence point?

19 views
Skip to first unread message

Argos

unread,
Feb 13, 2001, 10:15:55 AM2/13/01
to
Hi everyone,

I've noticed in a few discussions recently that the phrase "sequence
point" keeps popping up.

Alas I (and no-one else here) has any idea what it means.

Can someone please give me a simple definition?

Cheers in advance, Argos

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]

Erik Max Francis

unread,
Feb 13, 2001, 4:33:17 PM2/13/01
to
Argos wrote:

> I've noticed in a few discussions recently that the phrase "sequence
> point" keeps popping up.
>
> Alas I (and no-one else here) has any idea what it means.
>
> Can someone please give me a simple definition?

>From the C++ Standard, 1.9/7:

... Evaluation of an expression might produce side effects. At
certain specified points in the execution sequence called sequence
points, all side effects of previous evaluations shall be complete
and no side effects of subsequent evaluations shall have taken
place.

--
Erik Max Francis / m...@alcyone.com / http://www.alcyone.com/max/
__ San Jose, CA, US / 37 20 N 121 53 W / ICQ16063900 / &tSftDotIotE
/ \ Time is a storm in which we are all lost.
\__/ George Bernard Shaw
Alcyone Systems' CatCam / http://www.catcam.com/
What do your pets do all day while you're at work? Find out.

Ron Natalie

unread,
Feb 13, 2001, 4:35:05 PM2/13/01
to

Argos wrote:

> I've noticed in a few discussions recently that the phrase "sequence
> point" keeps popping up.
>
> Alas I (and no-one else here) has any idea what it means.
>
> Can someone please give me a simple definition?

I'd suggest you go back to the answer we provided to this very
question about two weeks ago in DejaNews, but Google has destroyed
DEJA and replaced it with their own ususable system (not invented
here sickness to the extreme).

A sequence point is defined in the C++ language as a point where
variables are in a known state, and all side effects are complete.
In general, order of operations in C++ is arbitrary:

f() + g() + j++;

You don't know if f() is executed before g() or after, or when the ++
is applied to j. All you know is that everything has been done when
the sequence point occurs.

Where are sequence points?

1. There is a sequence point at the end of each full expression (an
expression
not a part of any other). You can think of this as being at the ";" in
the
above statement.

2. There is a sequence point at the beginning (after the arguments are
evaluated)
and end of subroutines. Note that this one is slightly problematic
because
for example in the above example, even though a sequence point occurs
around the
execution of f(), you still don't know if it did g() first, etc....

3. There is a sequence point after the evaluation of the first operand of
a few "special" operators, notably the built-in comma, &&, ||, and ?:
operators.

In addition to putting things in a known state, the language puts some
specific
restrictions on the programmer. A variable may only be changed once between
sequence points:

k = x++ + x++;

is undefined behavior (the compiler need not do anything specific nor even
compile
the above expression).

Furthermore, if you change the value, you're not supposed to use it for
anythign else
inside the expression:

k = i++ + i;

Carlos Moreno

unread,
Feb 13, 2001, 6:51:12 PM2/13/01
to
Ron Natalie wrote:
>
> Furthermore, if you change the value, you're not supposed to use it for
> anythign else
> inside the expression:
>
> k = i++ + i;

Careful with your phrasing! Remember that you're explaining to
someone what sequence points are about... :-)

The value of a variable that is changed by can not be used until
the next occurence of a sequence point -- not "inside the
expression," as you said. The expression may involve sequence
points, as you mentioned previously in your message:

bool k = i++ > 0 || i > b;

Is perfectly valid, nad you're using i in the same expression
where a side effect took place.

Carlos
--
PS: I know you knew this one -- the only thing I'm pointing
out is that your phrasing may be confusing, given that
it is addressed to someone that is trying to understand
the sequence points.

Tom Plunket

unread,
Feb 14, 2001, 11:05:16 AM2/14/01
to
Carlos Moreno wrote:

> The value of a variable that is changed by can not be used until
> the next occurence of a sequence point -- not "inside the
> expression," as you said. The expression may involve sequence
> points, as you mentioned previously in your message:
>
> bool k = i++ > 0 || i > b;
>
> Is perfectly valid, nad you're using i in the same expression
> where a side effect took place.

I thought the standard allowed the different sides of the '||' to
be evaluated in any order. Is that incorrect, are you guaranteed
left-to-right execution of something like this?

In practice, I often do:

{
Something* s;
Compute(s);

if ((s != NULL) && (s.someState))
{
//...
}
}

...but always thought that the order of evaluation COULD be
right-to-left...

-tom!

--
Tom Plunket to...@fancy.org
PlayStation2/3D Studio geek
Change is inevitable. Progress is not.

Richard Parkin

unread,
Feb 14, 2001, 7:11:07 PM2/14/01
to

"Tom Plunket" <to...@fancy.org> wrote in message
news:6t6k8t8d2k14706un...@4ax.com...

> Carlos Moreno wrote:
>
> > The value of a variable that is changed by can not be used until
> > the next occurence of a sequence point -- not "inside the
> > expression," as you said. The expression may involve sequence
> > points, as you mentioned previously in your message:
> >
> > bool k = i++ > 0 || i > b;
> >
> > Is perfectly valid, nad you're using i in the same expression
> > where a side effect took place.
>
> I thought the standard allowed the different sides of the '||' to
> be evaluated in any order. Is that incorrect, are you guaranteed
> left-to-right execution of something like this?
>
> In practice, I often do:
>
> {
> Something* s;
> Compute(s);
>
> if ((s != NULL) && (s.someState))
> {
> //...
> }
> }
>
> ...but always thought that the order of evaluation COULD be
> right-to-left...

Ah, there we go - 5.15/1 "Unlike |, || guantees left-to-right evaluation.
Moreover, the second operand is not evaluated if the first operand evaluates
to true"

And similar for && in 5.14/1

So boolean short-circuiting *is* guarenteed.

Ric

Derekasaurus Rex

unread,
Feb 14, 2001, 7:13:14 PM2/14/01
to
"Tom Plunket" wrote ...

> Carlos Moreno wrote:
>
> > The value of a variable that is changed by can not be used until
> > the next occurence of a sequence point -- not "inside the
> > expression," as you said. The expression may involve sequence
> > points, as you mentioned previously in your message:
> >
> > bool k = i++ > 0 || i > b;
> >
> > Is perfectly valid, nad you're using i in the same expression
> > where a side effect took place.
>
> I thought the standard allowed the different sides of the '||' to
> be evaluated in any order. Is that incorrect, are you guaranteed
> left-to-right execution of something like this?
>
> In practice, I often do:
>
> {
> Something* s;
> Compute(s);
>
> if ((s != NULL) && (s.someState))
> {
> //...
> }
> }
>
> ...but always thought that the order of evaluation COULD be
> right-to-left...

5.14 Logical AND operator

"The && operator groups letf-to-right...Unlike &, &&
guarantees left-to-right evaluation: the second operand
is not evaluated if the first operand is false."

Similar rule for the || and conditional operator in 5.15
and 5.16. The || doesn't evaluate the second operand if the
first is true, and the conditional only evaluates one of
the second and third expressions.

Francis Glassborow

unread,
Feb 14, 2001, 8:42:34 PM2/14/01
to
In article <6t6k8t8d2k14706un...@4ax.com>, Tom Plunket
<to...@fancy.org> writes

>Carlos Moreno wrote:
>
>> The value of a variable that is changed by can not be used until
>> the next occurence of a sequence point -- not "inside the
>> expression," as you said. The expression may involve sequence
>> points, as you mentioned previously in your message:
>>
>> bool k = i++ > 0 || i > b;
>>
>> Is perfectly valid, nad you're using i in the same expression
>> where a side effect took place.
>
>I thought the standard allowed the different sides of the '||' to
>be evaluated in any order. Is that incorrect, are you guaranteed
>left-to-right execution of something like this?
>

Even that is less than what is required. The left-hand side must be
fully evaluated and all side effects complete before the rhs is even
considered. The rhs MUST NOT be evaluated unless the result is needed
to determine the boolean value of the complete expression. Of course
this is entirely different for user provided overloads of those
operators:)


--
Francis Glassborow
See http://www.accu.org for details of The ACCU Spring Conference, 2001
(includes many regular participants to C & C++ newsgroups)

Jorgen Grahn

unread,
Feb 14, 2001, 8:48:05 PM2/14/01
to
On 14 Feb 2001 11:05:16 -0500, Tom Plunket <to...@fancy.org> wrote:
...

>I thought the standard allowed the different sides of the '||' to
>be evaluated in any order. Is that incorrect, are you guaranteed
>left-to-right execution of something like this?
...

> if ((s != NULL) && (s.someState))

The standard guarantees that the above does exactly what you assume it does.
The term used for this in Stroustrup's book is 'short-circuit evaluation',
and it wouldn't work if && didn't introduce a sequence point.

(It's weird; most of the C and C++ code I write would break instantly if
this rule didn't apply, and still several experienced programmers I know are
not familiar with it. Like you, they use it, but are not convinced that
it's supposed to work. :-)

/Jorgen

--
// Jorgen Grahn <jgrahn@ ''Battle ye not with monsters,
\X/ algonet.se> lest ye become a monster''

Ron Natalie

unread,
Feb 15, 2001, 3:40:40 AM2/15/01
to

Tom Plunket wrote:

>
> I thought the standard allowed the different sides of the '||' to
> be evaluated in any order. Is that incorrect, are you guaranteed
> left-to-right execution of something like this?

For the built-in ||, certainly NOT! The left side of || is ALWAYS
executed first. A sequence point then occurs, then if the left side
is FALSE, the right side is executed.

This is why it's exteremely bogus to overload operator||. The overloaded
operator|| behaves like a regular function call (unspecified order and
both sides are always executed).

>
> In practice, I often do:
>
> {
> Something* s;
> Compute(s);
>
> if ((s != NULL) && (s.someState))
> {
> //...
> }
> }
>
> ...but always thought that the order of evaluation COULD be
> right-to-left...
>

Hopefully you meant s->someState (otherwise it won't compile).

If you thought that the order was arbitrary, and that short circuiting
didn't occur, why would you do such a thing? You'd be dereferencing
a null poitner.

Carlos Moreno

unread,
Feb 15, 2001, 3:50:46 AM2/15/01
to

Tom Plunket wrote:
>
> I thought the standard allowed the different sides of the '||' to
> be evaluated in any order.

Whoa! no! If that was true, then how would you guarantee shortcut
evaluation? Also, how could it make sense that || introduces a
sequence point if the expression may be evaluated in any order??
What would be the role of the sequence point in such case?

> In practice, I often do:
>
> {
> Something* s;
> Compute(s);
>
> if ((s != NULL) && (s.someState))

I'll assume you meant s->someState

> ...but always thought that the order of evaluation COULD be
> right-to-left...

If the compiler were allowed to evaluate that in any order,
then your code would be severely broken -- you might be
dereferencing a NULL pointer, and only at the marcy of the
compiler! :-)

Cheers,

Carlos
--

Claude Quézel

unread,
Feb 15, 2001, 8:45:18 AM2/15/01
to


Tom Plunket wrote:

>
>
> ...but always thought that the order of evaluation COULD be
> right-to-left...
>
> -tom!

No. The language garantees short circuit evaluation from left to right.
That is why it is not well advised to overload &&, ||, and ,. When these
are functions, they dont behave as their operator counterpart.

Claude

--

Claude Quézel (claude...@syntell.corba)
anti-spam: replace corba by com in private replies

Joseph Chakravarti

unread,
Feb 15, 2001, 11:21:25 AM2/15/01
to
>From http://www.cygnus.com/misc/wp/dec96pub/intro.html:

"Accessing an object designated by a volatile lvalue (_basic.lval_),
modifying an object, calling a library I/O function, or calling a
function that does any of those operations are all side effects, which
are changes in the state of the execution environment. Evaluation of


an expression might produce side effects. At certain specified points
in the execution sequence called sequence points, all side effects of

previous evaluations shall be complete and no side effects of subse-
quent evaluations shall have taken place.5)

Thomas Paul Diffenbach

unread,
Feb 19, 2001, 1:17:32 AM2/19/01
to
Hello, Tom Plunket !
You wrote:

> I thought the standard allowed the different sides of the '||'
to
> be evaluated in any order. Is that incorrect, are you
guaranteed
> left-to-right execution of something like this?
>
> In practice, I often do:
>

> if ((s != NULL) && (s.someState))
>

> ...but always thought that the order of evaluation COULD be
> right-to-left...

If you thought the evaluation could be right-to-left, how did you
think this idiom could possibly be safe?
(Of course, as written, it won't compile if s is a pointer. Maybe
that's what makes it safe?)

--
末Thomas Paul Diffenbach
reply to t...@diffenbach.org
I realized, so suddenly and so forcefully that it cannot but be
true: there are no epiphanies.

Tom Plunket

unread,
Feb 19, 2001, 9:27:33 PM2/19/01
to

First of all, thank you everyone for picking nits. It just
wouldn't be the same without people picking up on obvious syntax
problems (that are often not noticed when whipping something up
"for example" in the newsgroup). I'm sure we all benefitted from
the large number of people pointing out that pointer
dereferencing need '->' rather than '.'

> Tom Plunket writes


>
> >I thought the standard allowed the different sides of the '||' to
> >be evaluated in any order. Is that incorrect, are you guaranteed
> >left-to-right execution of something like this?
> >

Francis Glassborow wrote:

> Even that is less than what is required. The left-hand side must be
> fully evaluated and all side effects complete before the rhs is even
> considered. The rhs MUST NOT be evaluated unless the result is needed
> to determine the boolean value of the complete expression. Of course
> this is entirely different for user provided overloads of those
> operators:)

Thank you- this is what I was looking for. Not a discussion
about "if you can't guarantee it, why do you do it?" I mean,
it's not as if I didn't say explicitly that "in practice this is
the way it works," or anything. Sheesh, you people sometimes...

-tom!

--
Tom Plunket to...@fancy.org
PlayStation2/3D Studio geek

What do you mean, it doesn't work? It worked fine yesterday...

Carlos Moreno

unread,
Feb 20, 2001, 8:09:50 PM2/20/01
to

Tom Plunket wrote:
>
> > Even that is less than what is required. The left-hand side must be
> > fully evaluated and all side effects complete before the rhs is even
> > considered. The rhs MUST NOT be evaluated unless the result is needed
> > to determine the boolean value of the complete expression. Of course
> > this is entirely different for user provided overloads of those
> > operators:)
>
> Thank you- this is what I was looking for. Not a discussion
> about "if you can't guarantee it, why do you do it?" I mean,
> it's not as if I didn't say explicitly that "in practice this is
> the way it works," or anything. Sheesh, you people sometimes...

Well, our messages were, in a sense, elaborating a bit more in
what you were saying, rather than simply pointing out the rules.

If you can't accept corrections and take offense by anyone pointing
out something wrong in what you said, maybe this is the wrong place
for you to be... Also, you simply can not expect that every single
individual in here replies to you in the exact way and telling you
*exactly* what you expect. Different people notices different
details and react differently. Please don't feel offended or
bothered by that. It's the variety of points of views what makes
this an interesting place to be!

As an example, check my posts in the past three or four days.
You'll see that John "nit picked" on me (according to your standards)
like, a million times... Well, even though they were obvious
oversights when I was writing them, it's always good to point out
the errors, in case other people (less skilled, maybe) are confused
or misled by the errors.

Sure, that doesn't mean that John, or someone else, is going to
say or suggest that I have no idea what I'm talking about, that I
should take a beginner's book and learn some C++ before posting, or
any other kind of rude comments! They probably see (as we did with
your message) that it was an obvious oversight, a distraction...
Still, it's worth pointing out the detail, as long as it is done
in a respectful way (which I believe we all did when replying
to your message).

Cheers,

Carlos
--

Reply all
Reply to author
Forward
0 new messages