 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
James Kanze Guest
|
Posted: Mon Jul 07, 2003 1:14 am Post subject: Re: Post Increment/decrement operator suggestion. |
|
|
[email]dhruvbird (AT) gmx (DOT) net[/email] ("Dhruv") writes:
| Quote: | On Thu, 03 Jul 2003 23:48:24 +0000, Ron Natalie wrote:
You modify b and use it for purposes other than that
modification between sequence points. You have to look at all
the allowable orderings. The compiler is perfectly free to
evalutate the first b and the b++ expression before calling any
of the function calls.
Ok, so what you are saying is that the compiler may/may not
evaluate b++ before putting b on the stream? Did I get that right?
|
No. What he is saying is that your program is illegal. But because
it involves undefined behavior, the compiler is not required to emit a
diagnostic -- in fact, there exist no requirements what so ever as to
what the compiler does.
| Quote: | Ok, which section/para in the steandard is all this input coming
from. I searched, but could only find: 5.2.2 which is function
call. I was looking for what James Kanze has quoted, about the
side effects of the expressions...... Where is it?
|
See my other posting. Plus, of course, 1.9, which defines sequence
points and the required behavior of a program relative to them.
--
James Kanze mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France Tel. +33 1 41 89 80 93
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
|
|
| Back to top |
|
 |
James Kanze Guest
|
Posted: Mon Jul 07, 2003 1:14 am Post subject: Re: Post Increment/decrement operator suggestion. |
|
|
[email]dhruvbird (AT) gmx (DOT) net[/email] ("Dhruv") writes:
| Quote: | On Tue, 01 Jul 2003 23:44:45 +0000, James Kanze wrote:
|> >Look at this code:
|> >int foo (int x) { return x; }
|> >int main ()
|> >{
|> > int b = 5;
|> > cout<
|> > cout<
|> >}
|> >The output is something like:
|> >6
|> >5
|> >6
|> But you are passing by value, now declare foo as:
|> int foo(int & x);
|> and see what you get now.
He still gets undefined behavior. Except that if foo takes a
non-const reference, the compiler is required to emit a
diagnostic, because the result of post-incrementation is not an
lvalue.
I'm not sure what point he is trying to make. The standard
seems pretty clear to me with regards to the following points:
- a function call is a sequence point, all side effects of
previously evaluated expressions must take place before the
function call, and
- the results of a post-fix incrementation operator is the
value of the operand before the incrementation.
I agreed with you fully on what you have just said.
|
I don't think so.
| Quote: | Even the example that I gave is proof that what you said is 100%
correct.
|
No example can prove anything with regards to what I said, since
anything the compiler does is legal. With luck, the code won't
compile, but it practice, it is extremely difficult for a compiler to
detect this particular error, and most don't.
| Quote: | See the output: 6 5 6.
|
The output means nothing. With another compiler, it could be 42 59
103. Or the program core dumps. Or it doesn't compile.
| Quote: | That's cause streams a kinda backwards, so when the first thing
(foo(b++)) is evaluated, foo gets 5, b becomes 6, then b is put on
the stream, because of the reverse nature of streams, and you see
b as 6, which it actually is. Intuituvely, you would expect b to
be 5 here, but it's not.
|
I don't think you understand either what I am saying, nor really what
is going on. What I am saying is that the code is illegal. What is
happening is that the compiler is assuming that it doesn't have to
deal with such code, so is making no particular effort to get any
particular results.
| Quote: | What point I'm trying to make has been lost (well, not actually).
This post started out as a proposal to have ++(int) behave
differently that what it does now, and it seems that if it is,
then many of the things that people expect form post increment
would be lost especially for function calls, where as you said,
the expression should be evaluated before the function call.
|
Let's just say that changing that would break more than a few
programs.
--
James Kanze mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France Tel. +33 1 41 89 80 93
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
|
|
| Back to top |
|
 |
Bo Persson Guest
|
Posted: Mon Jul 07, 2003 7:00 pm Post subject: Re: Post Increment/decrement operator suggestion. |
|
|
"James Kanze" <kanze (AT) alex (DOT) gabi-soft.fr> wrote...
[email]dhruvbird (AT) gmx (DOT) net[/email] ("Dhruv") writes:
| Quote: | What point I'm trying to make has been lost (well, not actually).
This post started out as a proposal to have ++(int) behave
differently that what it does now, and it seems that if it is,
then many of the things that people expect form post increment
would be lost especially for function calls, where as you said,
the expression should be evaluated before the function call.
|
The problem here is that there are *several* function calls in the
full expression. The standars says that each function call will have
*its* parameters fully evaluated before the call. It doesn't say
whether other functions can or cannot have *their* parameters fully or
partially evaluated before or after (or both) any other function call.
The compiler will evaluate all the parameters in the best (like
"fastest") way it can find. This can mean that it computes all, some,
or partial, expressions before and/or between each function call. The
only restriction is that for each function, its parameters are fully
evaluated before the function is called. As a programmer, your only
promise is that you won't change the value of any subexpression the
compiler might already have evaluated.
In your case this subexpression is simply b, which is used twice. As
the value is not allowed to change within the expression (because it
is used more than once), the compiler is smart and loads it from
memory only once.
| Quote: | Let's just say that changing that would break more than a few
programs.
|
Understatement of the week. The suggestion is about 30 years too late.
:-)
Bo Persson
[email]bop2 (AT) telia (DOT) com[/email]
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
|
|
| Back to top |
|
 |
Dhruv Guest
|
Posted: Wed Jul 09, 2003 2:42 am Post subject: Re: Post Increment/decrement operator suggestion. |
|
|
On Mon, 07 Jul 2003 01:14:06 +0000, James Kanze wrote:
| Quote: | dhruvbird (AT) gmx (DOT) net ("Dhruv") writes:
|> On Thu, 03 Jul 2003 23:48:24 +0000, Ron Natalie wrote:
|> > You modify b and use it for purposes other than that
|> > modification between sequence points. You have to look at all
|> > the allowable orderings. The compiler is perfectly free to
|> > evalutate the first b and the b++ expression before calling any
|> > of the function calls.
|> Ok, so what you are saying is that the compiler may/may not
|> evaluate b++ before putting b on the stream? Did I get that right?
No. What he is saying is that your program is illegal. But because
it involves undefined behavior, the compiler is not required to emit a
diagnostic -- in fact, there exist no requirements what so ever as to
what the compiler does.
|> Ok, which section/para in the steandard is all this input coming
|> from. I searched, but could only find: 5.2.2 which is function
|> call. I was looking for what James Kanze has quoted, about the
|> side effects of the expressions...... Where is it?
See my other posting. Plus, of course, 1.9, which defines sequence
points and the required behavior of a program relative to them.
|
Let's see if I got it right now. I'm writing down what I have gathered
from all this:
cout<
"Except where noted, the order of evaluation of operands of individual
operators and subexpressions of individual expressions, and the order
in which side effects take place, is unspecified. Between the previ-
ous and next sequence point a scalar object shall have its stored
value modified at most once by the evaluation of an expression. Fur-
thermore, the prior value shall be accessed only to determine the
value to be stored. The requirements of this paragraph shall be met
for each allowable ordering of the subexpressions of a full expres-
sion; otherwise the behavior is undefined."
Ok, so this is invalid, because:
1. The order of evaluation of the expressions is unspecified.
2. Here, the sequence points are the << operators. Right?, so we have to
access the value of 'b' in the full expression only once, and that too
only so that we can modify. Here, it is being used twice, once to modify
it, and once by cout. Or is it that we can access the value only once
between the sequence points?
"9) The sequence point at the function return is not explicitly speci-
fied in ISO C, and can be considered redundant with sequence points at
full-expressions, but the extra clarity is important in C++. In C++,
there are more ways in which a called function can terminate its exe-
cution, such as the throw of an exception."
So, am I right about the sequence points being at the place where the
operator<< is seen? Or is it unspecified, because the function return is
being used here? If not, where is it specified?
"8 The order of evaluation of arguments is unspecified. All side effects
of argument expression evaluations take effect before the function is
entered. The order of evaluation of the postfix expression and the
argument expression list is unspecified."
Does this apply here? So, what it's trying to say is that the order in
which the postfix expressions may be evaluated is unspecified?
And, as Bo Persson said, that the compiler will evaluate the parameters
before the functions call, but if there are multiple function calls in
the full expression, then there is no guaranrtee that the parameters for one will be
evaluated before the the other? So, is it somehitng like:
Suppose time is a "time" class, and t is an object of time.
t.add_hrs(add (23, 56)).add_min (add (34, 49)).add_sec(sub (23, 12));
So, here, it is not specified whether add (23, 56) is called first, or add
(34, 49) or sub(23, 12) is called first? Have I understood it right?
However, function return is used to evaluate the full expression. I think that
add_hrs will be called first, then add_min, and then add_sec, but cannot
find any proof in the standard that says anything about it? Am I right
here?
Regards,
-Dhruv.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Thu Jul 10, 2003 3:44 am Post subject: Re: Post Increment/decrement operator suggestion. |
|
|
In article <pan.2003.07.08.05.20.30.782471 (AT) gmx (DOT) net>, Dhruv
<dhruvbird (AT) gmx (DOT) net> writes
| Quote: | 2. Here, the sequence points are the << operators. Right?, so we have to
access the value of 'b' in the full expression only once, and that too
only so that we can modify. Here, it is being used twice, once to modify
it, and once by cout. Or is it that we can access the value only once
between the sequence points?
|
Wrong, or at least partially so. Unfortunately despite appearances from
the wording of the C and C++ standards there is not a strict ordering of
sequence points, i.e. they do not provide a sequence of events; they can
be nested so the sequence point at a function call only ensures that the
arguments of the function call have been written back. As all the
arguments for all the functions may be evaluated before any are called
the sequence points at the function calls do not protect the evaluation
of the arguments.
The correct way to look at the evaluation of an expression is to look at
it bottom up and to treat it as if all arguments and reads take place
before any function calls. In addition any writes that are independent
of function calls also take place. If the result is that a value that is
somewhere written in that sequence is also read independently (i.e. not
for the purpose of determining what should be written) of that write
then we have undefined behaviour.
--
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
|
|
| Back to top |
|
 |
Bart van Ingen Schenau Guest
|
Posted: Thu Jul 10, 2003 3:44 am Post subject: Re: Post Increment/decrement operator suggestion. |
|
|
On Wed, 9 Jul 2003 02:42:24 +0000 (UTC), [email]dhruvbird (AT) gmx (DOT) net[/email] ("Dhruv")
wrote:
| Quote: | On Mon, 07 Jul 2003 01:14:06 +0000, James Kanze wrote:
[email]dhruvbird (AT) gmx (DOT) net[/email] ("Dhruv") writes:
|> On Thu, 03 Jul 2003 23:48:24 +0000, Ron Natalie wrote:
|> > You modify b and use it for purposes other than that
|> > modification between sequence points. You have to look at all
|> > the allowable orderings. The compiler is perfectly free to
|> > evalutate the first b and the b++ expression before calling any
|> > of the function calls.
|> Ok, so what you are saying is that the compiler may/may not
|> evaluate b++ before putting b on the stream? Did I get that right?
No. What he is saying is that your program is illegal. But because
it involves undefined behavior, the compiler is not required to emit a
diagnostic -- in fact, there exist no requirements what so ever as to
what the compiler does.
|> Ok, which section/para in the steandard is all this input coming
|> from. I searched, but could only find: 5.2.2 which is function
|> call. I was looking for what James Kanze has quoted, about the
|> side effects of the expressions...... Where is it?
See my other posting. Plus, of course, 1.9, which defines sequence
points and the required behavior of a program relative to them.
Let's see if I got it right now. I'm writing down what I have gathered
from all this:
cout<
"Except where noted, the order of evaluation of operands of individual
operators and subexpressions of individual expressions, and the order
in which side effects take place, is unspecified. Between the previ-
ous and next sequence point a scalar object shall have its stored
value modified at most once by the evaluation of an expression. Fur-
thermore, the prior value shall be accessed only to determine the
value to be stored. The requirements of this paragraph shall be met
for each allowable ordering of the subexpressions of a full expres-
sion; otherwise the behavior is undefined."
Ok, so this is invalid, because:
1. The order of evaluation of the expressions is unspecified.
|
Correct.
| Quote: |
2. Here, the sequence points are the << operators. Right?
|
No, the operator<< does not introduce a sequence point.
And the sequence points introduced by a function call and return do
not apply the the entire expression, but only to respectively the
arguments of the function being called and the use of the return
value.
If we add numbers to the << operators for easy reference, the rules
imposed by the sequence points are:
In the statement
cout <<1 b <<2 foo(b++) <<3 endl;
- cout and b must be evaluated before <<1
- b++ must be evaluated before the call to foo()
- foo(b++) and <<1 must be evaluated before <<2
- <<2 and endl must be evaluated before <<3
- There is no ordering requirement on b, b++ and endl with respect to
each other.
- There is no ordering requirement on b, foo(b++) and endl with
respect to each other.
This can be made visual by writing the statement as nested function
calls:
operator<<3(operator<<2(operator<<1(cout, b), foo(b++)), endl);
The only explicit requirement here is that some time before the call
to a function, the arguments to that function must have been
evaluated.
| Quote: | , so we have to
access the value of 'b' in the full expression only once, and that too
only so that we can modify. Here, it is being used twice, once to modify
it, and once by cout. Or is it that we can access the value only once
between the sequence points?
|
You can access multiple times between sequence points, otherwise an
expression like 'b+b' would be invalid.
| Quote: |
"9) The sequence point at the function return is not explicitly speci-
fied in ISO C, and can be considered redundant with sequence points at
full-expressions, but the extra clarity is important in C++. In C++,
there are more ways in which a called function can terminate its exe-
cution, such as the throw of an exception."
So, am I right about the sequence points being at the place where the
operator<< is seen? Or is it unspecified, because the function return is
being used here? If not, where is it specified?
|
As explained above, the order is partially specified.
| Quote: |
"8 The order of evaluation of arguments is unspecified. All side effects
of argument expression evaluations take effect before the function is
entered. The order of evaluation of the postfix expression and the
argument expression list is unspecified."
Does this apply here? So, what it's trying to say is that the order in
which the postfix expressions may be evaluated is unspecified?
|
The requirement is in effect here, but it does not affect the outcome
for the statement in question.
The postfix expression referenced in the quote above is in this case
the function name, respectively the operator name.
| Quote: |
And, as Bo Persson said, that the compiler will evaluate the parameters
before the functions call, but if there are multiple function calls in
the full expression, then there is no guaranrtee that the parameters for one will be
evaluated before the the other? So, is it somehitng like:
Suppose time is a "time" class, and t is an object of time.
t.add_hrs(add (23, 56)).add_min (add (34, 49)).add_sec(sub (23, 12));
So, here, it is not specified whether add (23, 56) is called first, or add
(34, 49) or sub(23, 12) is called first? Have I understood it right?
However, function return is used to evaluate the full expression. I think that
add_hrs will be called first, then add_min, and then add_sec, but cannot
find any proof in the standard that says anything about it? Am I right
here?
|
You are right.
The reason that the functions add_hrs(), add_min() and add_sec() must
be called in that order is because add_min() operates on the object
returned by add_hrs() and there is no requirement that add_hrs()
returns t (or even an object of class time). The same argument holds
for add_min() and add_sec().
| Quote: |
Regards,
-Dhruv.
Bart v Ingen Schenau |
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
|
|
| Back to top |
|
 |
Ron Natalie Guest
|
Posted: Thu Jul 10, 2003 3:50 am Post subject: Re: Post Increment/decrement operator suggestion. |
|
|
""Dhruv"" <dhruvbird (AT) gmx (DOT) net> wrote
| Quote: | 2. Here, the sequence points are the << operators. Right?,
|
The sequqence point is the call to the operator<< function.
| Quote: | so we have to
access the value of 'b' in the full expression only once, and that too
only so that we can modify. Here, it is being used twice, once to modify
it, and once by cout.
|
Precisely. It is possible that the first evaluation of b (for cout) and the
b++ are both executed before either of the operator<< functions (and their
inherent sequence points).
| Quote: | Or is it that we can access the value only once
between the sequence points?
|
No, you can access it as many times as you want provided you don't also modify it.
| Quote: | So, am I right about the sequence points being at the place where the
operator<< is seen? Or is it unspecified, because the function return is
being used here? If not, where is it specified?
|
It has nothing to do with being "seen." It has to do when things are executed.
| Quote: |
Does this apply here? So, what it's trying to say is that the order in
which the postfix expressions may be evaluated is unspecified?
|
Yes, but it applies in that is allows the operator<< calls in your example
expression to be executed in an order that causes both subexpressions
involving b to be invoked before any function call (and the inherent sequence
points).
| Quote: |
And, as Bo Persson said, that the compiler will evaluate the parameters
before the functions call, but if there are multiple function calls in
the full expression, then there is no guaranrtee that the parameters for one will be
evaluated before the the other?
|
Preciesly.
| Quote: | t.add_hrs(add (23, 56)).add_min (add (34, 49)).add_sec(sub (23, 12));
So, here, it is not specified whether add (23, 56) is called first, or add
(34, 49) or sub(23, 12) is called first?
|
That is correct. And they all can be called before any of the add_hrs, add_min, or add_sec.
On the ohter hand, they can be called at the last possible instance before the value is needed
Two of the possible orderings:
sub(23,12)
add(23,56)
add(34,59)
add_hrs
add_min
add_sec
or
add(23,56)
add_hrs
add(34,49)
add_min
sub(23.12)
add_sec.
| Quote: | However, function return is used to evaluate the full expression. I think that
add_hrs will be called first, then add_min, and then add_sec, but cannot
find any proof in the standard that says anything about it? Am I right
here?
Well, it's pretty hard for the compiler to come up with the return value without |
calling the function. That pretty much implies that add_hrs has to be called before
add_min etc...
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
|
|
| Back to top |
|
 |
Bart van Ingen Schenau Guest
|
Posted: Tue Jul 15, 2003 3:01 am Post subject: Re: Post Increment/decrement operator suggestion. |
|
|
On Fri, 11 Jul 2003 17:49:40 +0000 (UTC), [email]dhruvbird (AT) gmx (DOT) net[/email] ("Dhruv")
wrote:
| Quote: |
Now, I'd like to confirm something:
1. "> No, the operator<< does not introduce a sequence point.
And the sequence points introduced by a function call and return do not
apply the the entire expression, but only to respectively the arguments
of the function being called and the use of the return value."
By this you mean that the arguments of a function, like operator<<(cout,
b) have to be evaluated before the function call, but the order in which
this happens is unspecified by the above, but the return value will
be obtained ONLY after the evaluation of the function, that is at the end
of the function sequence point. This has got nothing to do with the full
expression.
And, while finding out what will be evaluated in the full expression, we
consider the sequence points to be at the beginning and end of that full
expression. Like this:
*operator<<3(operator<<2(operator<<1(cout, b), foo(b++)), endl);*
Where, the '*' denotes the sequence point.
Similarly, if we wanted to find out the order of evaluation of foo (b++)
and <<2 wrt each other, we have to mark the sequence points as such:
*operator<<3*(operator<<2*(operator<<1(*cout*, *b*)*, *foo(b++)*)*, *endl*);*
So, basically, we can never in such cases (where function calls are
embedeed within each other) determine the order of evaluation of
individual function parameters wrt each other right?
So, for operator<<3 (arg1, arg2). If arg1, and arg2 are both function
calls, then which is evaluated first is not specified, but if arg1 =
foo(bar (23, 56), 45), and arg2 = bar (12, 99), then, it is specified that
bar(23, 56) will be evaluated before foo (bar(), 45), but still the order
of bar (23, 56) is unspecified wrt. bar (12, 99), because the order of
arg1, wrt arg2 is unspecified.
Am I right here?
|
Yes, you are completely right.
| Quote: | On Thu, 10 Jul 2003 03:44:42 +0000, Bart van Ingen Schenau wrote:
On Wed, 9 Jul 2003 02:42:24 +0000 (UTC), [email]dhruvbird (AT) gmx (DOT) net[/email] ("Dhruv")
wrote:
, so we have to
access the value of 'b' in the full expression only once, and that too
only so that we can modify. Here, it is being used twice, once to modify
it, and once by cout. Or is it that we can access the value only once
between the sequence points?
You can access multiple times between sequence points, otherwise an
expression like 'b+b' would be invalid.
Sorry, I meant access it only once if it is being modified, and that
access should be only to read the value. (to be modified).
|
Yes, that is correct.
In fact, you used almost the same wording as the standard does. :-)
| Quote: |
Regards,
-Dhruv.
Bart v Ingen Schenau |
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
|
|
| Back to top |
|
 |
Dhruv Guest
|
Posted: Wed Jul 16, 2003 4:47 pm Post subject: Re: Post Increment/decrement operator suggestion. |
|
|
On Tue, 15 Jul 2003 03:01:27 +0000, Bart van Ingen Schenau wrote:
[snip]......
| Quote: | Am I right here?
Yes, you are completely right.
[snip]...... |
| Quote: | Sorry, I meant access it only once if it is being modified, and that
access should be only to read the value. (to be modified).
Yes, that is correct.
In fact, you used almost the same wording as the standard does. :-)
|
Thanks a lot :-)
Regards,
-Dhruv.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|