Topic: Why Right-to-left?
Author: kanze@alex.gabi-soft.fr (James Kanze)
Date: Sun, 4 May 2003 21:43:39 +0000 (UTC) Raw View
do-not-spam-ben.hutchings@businesswebsoftware.com (Ben Hutchings) writes:
|> In article <86bryshtum.fsf@alex.gabi-soft.fr>, James Kanze wrote:
|> > brangdon@cix.co.uk (Dave Harris) writes:
|> <snip>=20
|> >|> We should be concerned about space overhead as well as
|> >|> time. And of course, one extra instruction might be enough to
|> >|> cause a CPU cache line overflow.
|> > The function call, or at the very least, the return, will purge
|> > the pipeline.
|> First of all, he said *cache* line, not pipeline. Secondly,
|> modern processors are quite capable of decoding a function call or
|> return early in the pipeline and altering instruction fetch
|> quickly enough to avoid the need for a purge. Even those without
|> a link register.
Which ones? The older HP Unix machines weren't; I don't know if
they've improved this since. And my timing measures on current Sun
Sparcs suggest that they don't either.
--=20
James Kanze mailto:kanze@gabi-soft.fr
Conseils en informatique orient=E9e 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 ]
Author: do-not-spam-ben.hutchings@businesswebsoftware.com (Ben Hutchings)
Date: Wed, 7 May 2003 04:27:02 +0000 (UTC) Raw View
In article <86ptmyh0c7.fsf@alex.gabi-soft.fr>, James Kanze wrote:
> do-not-spam-ben.hutchings@businesswebsoftware.com (Ben Hutchings) writes:
>
>|> In article <86bryshtum.fsf@alex.gabi-soft.fr>, James Kanze wrote:
>|> > brangdon@cix.co.uk (Dave Harris) writes:
>|> <snip>
>|> >|> We should be concerned about space overhead as well as
>|> >|> time. And of course, one extra instruction might be enough to
>|> >|> cause a CPU cache line overflow.
>
>|> > The function call, or at the very least, the return, will purge
>|> > the pipeline.
>
>|> First of all, he said *cache* line, not pipeline. Secondly,
>|> modern processors are quite capable of decoding a function call or
>|> return early in the pipeline and altering instruction fetch
>|> quickly enough to avoid the need for a purge. Even those without
>|> a link register.
>
> Which ones? The older HP Unix machines weren't; I don't know if
> they've improved this since. And my timing measures on current Sun
> Sparcs suggest that they don't either.
Any recent POWER, PowerPC, SPARC, x86, or MIPS. Google for "return
address stack". You might be getting bad results on a SPARC because
of a gcc mis-optimisation for SPARC that defeated this feature
<http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&pr=6496>.
---
[ 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 ]
Author: do-not-spam-ben.hutchings@businesswebsoftware.com (Ben Hutchings)
Date: Tue, 29 Apr 2003 05:49:47 +0000 (UTC) Raw View
In article <86bryshtum.fsf@alex.gabi-soft.fr>, James Kanze wrote:
> brangdon@cix.co.uk (Dave Harris) writes:
<snip>
>|> We should be concerned about space overhead as well as time. And
>|> of course, one extra instruction might be enough to cause a CPU
>|> cache line overflow.
>
> The function call, or at the very least, the return, will purge the
> pipeline.
First of all, he said *cache* line, not pipeline. Secondly, modern
processors are quite capable of decoding a function call or return
early in the pipeline and altering instruction fetch quickly enough
to avoid the need for a purge. Even those without a link register.
---
[ 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 ]
Author: brangdon@cix.co.uk (Dave Harris)
Date: Mon, 28 Apr 2003 03:10:23 +0000 (UTC) Raw View
nid_oizo@yahoo.com_removethe_ (Nicolas Fleury) wrote (abridged):
> I think the request is compatible with that design objective. Like I
> said before, optimizers often ignore sequence points if they can
> conclude or assume the optimized code has the same results.
And as has been pointed out, they can't always do that.
> I think the statu quo is a mistake because of another design
> objective: have a multi-platform language. How can a language be
> the multi-platform is this simple code produces different results
> depending on compiler:
C++ has ways to enforce consistent results where that matters.
> Like others, I just want all the code I produce to have a defined and
> intuitive behaviour. It removes some language gotchas and makes code
> more portable and reproduceable. I really think it's worth the cost.
I agree, in that it would help me too. I am wondering if this is because
the design aims of C++ do not exactly suit what I am doing. If so, then
perhaps we should revise those aims, or else switch to a different
language.
Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
brangdon@cix.co.uk | And close your eyes with holy dread,
| For he on honey dew hath fed
http://www.bhresearch.co.uk/ | And drunk the milk of Paradise."
---
[ 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 ]
Author: kanze@alex.gabi-soft.fr (James Kanze)
Date: Mon, 28 Apr 2003 03:10:36 +0000 (UTC) Raw View
brangdon@cix.co.uk (Dave Harris) writes:
|> kanze@gabi-soft.de (James Kanze) wrote (abridged):
|> > > A C compiler [...] would be more efficient for the same source
|> > > code.
|> > The question is: would it?
|> I thought this had been established elsewhere in the thread, eg
|> Ron Natalie's article posted on the 20th March.
Nothing has really been established. Ron posted a case where it might
be, and a case which certainly should be considered. It is, however,
impossible to determine exactly whether a compiler would be more or
less efficient without fully considering the context where the
expression might occur, and the types of optimization that one can
reasonably expect of the compiler. (Not the types of optimization
theoretically possible, but those which one can reasoanbly expect.)
|> As I understand it, you can argue that the difference is
|> insignificant, but not that there is no difference.
I don't doubt that for at least some architectures, you can create
artificial programs where there will be a difference. The question is
whether it will make a measurable difference in real programs.
Anything less than 1% is not measurable. Not 1% in an isolated
statement, of course, but 1% in the total execution time of the
critical path.
|> > but the function call alone will typically take ten times the
|> > time of the extra instruction.
|> We should be concerned about space overhead as well as time. And
|> of course, one extra instruction might be enough to cause a CPU
|> cache line overflow.
The function call, or at the very least, the return, will purge the
pipeline.
Let's be realistic. Ron posted a concrete example, which IMHO must be
taken into account. But vague speculation about cache line
overflow...
--=20
James Kanze mailto:kanze@gabi-soft.fr
Conseils en informatique orient=E9e 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Mon, 28 Apr 2003 20:25:30 +0000 (UTC) Raw View
Dave Harris wrote:
> I am wondering if this is because the design aims of C++ do not
> exactly suit what I am doing. If so, then perhaps we should revise
> those aims, or else switch to a different language.
C++ uses C's design by default, so it may be that no one examined
C++'s aims in this area, or just decided to leave things be. One
consideration might be for compilers which translate C++ to C. It
may make their work harder if they have to implement a defined
execution order when C doesn't have it.
---
[ 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 ]
Author: brangdon@cix.co.uk (Dave Harris)
Date: Fri, 25 Apr 2003 18:03:24 +0000 (UTC) Raw View
kanze@gabi-soft.de (James Kanze) wrote (abridged):
> > A C compiler [...] would be more efficient for the same source
> > code.
>
> The question is: would it?
I thought this had been established elsewhere in the thread, eg Ron
Natalie's article posted on the 20th March.
As I understand it, you can argue that the difference is insignificant,
but not that there is no difference.
> but the function call alone will typically take ten times the time
> of the extra instruction.
We should be concerned about space overhead as well as time. And of
course, one extra instruction might be enough to cause a CPU cache line
overflow.
Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
brangdon@cix.co.uk | And close your eyes with holy dread,
| For he on honey dew hath fed
http://www.bhresearch.co.uk/ | And drunk the milk of Paradise."
---
[ 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 ]
Author: nid_oizo@yahoo.com_removethe_ (Nicolas Fleury)
Date: Sun, 20 Apr 2003 21:40:03 +0000 (UTC) Raw View
Allan W wrote:
> You keep saying that, as if the number was on page 217 of "The big secret
> book of optimization costs."
This is *your* intepretation.
> In fact, making this type of measurement is
> a Big Deal(tm).
Yes, it is a big deal, but what I am saying is that "if no one is able
to justify the statu quo, let's change it to make the language more
intuitive and reproduceable".
> I highly suggest that you try it yourself. Download G++ source code,
> then modify it to order evaluations the same way that Java does. Be sure
> to remove any optimizations that prohibit this type of reordering.
> Compile and test your mods, until you're sure that (other than defining
> the order of operations) it still works identically to the first version.
> Then do some timing tests and report back here.
>
> Go ahead.
>
> I'll wait.
>
> Go ahead! I'm waiting.
>
> I'll just wait over here...
You don't get it. I don't want to do it myself, and I humblely don't
have the competences to do it. I don't want to do it also 'cause I'm
more interested in a C++ easier to use, in the specific case we're
talking about, than in a maximally optimized C++. You're defending the
statu quo, so why it shouldn't be to *you* to justify it? Yes, me and
others are proposing a change, but there's no backward-compatibility
involved! Right now, stuff like "func1(func2(),func3());" have an
undefined behaviour, and I don't think it's acceptable for a
multi-platform language. Having a java-like execution order would
produce slightly slower code? To me this *is not* a big deal.
Regards,
Nicolas Fleury
---
[ 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 ]
Author: brangdon@cix.co.uk (Dave Harris)
Date: Mon, 21 Apr 2003 11:41:08 +0000 (UTC) Raw View
nid_oizo@yahoo.com_removethe_ (Nicolas Fleury) wrote (abridged):
> Having a java-like execution order would produce slightly slower
> code? To me this *is not* a big deal.
It is a C++ design objective to leave no room for a lower level language,
other than assembler. Do you think your request for defined orders of
evaluation is compatible with that design objective? Or do you think the
objective should be dropped now?
Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
brangdon@cix.co.uk | And close your eyes with holy dread,
| For he on honey dew hath fed
http://www.bhresearch.co.uk/ | And drunk the milk of Paradise."
---
[ 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 ]
Author: qrczak@knm.org.pl ("Marcin 'Qrczak' Kowalczyk")
Date: Mon, 21 Apr 2003 12:08:04 +0000 (UTC) Raw View
Dave Harris wrote:
> It is a C++ design objective to leave no room for a lower level language,
> other than assembler. Do you think your request for defined orders of
> evaluation is compatible with that design objective?
Well, assemblers have explicit order of evaluation, so I don't understand
why you say it would make C++ too high level.
--
__("< Marcin Kowalczyk
\__/ qrczak@knm.org.pl
^^ http://qrnik.knm.org.pl/~qrczak/
---
[ 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 ]
Author: nid_oizo@yahoo.com_removethe_ (Nicolas Fleury)
Date: Mon, 21 Apr 2003 17:31:03 +0000 (UTC) Raw View
Dave Harris wrote:
> nid_oizo@yahoo.com_removethe_ (Nicolas Fleury) wrote (abridged):
>
>>Having a java-like execution order would produce slightly slower
>>code? To me this *is not* a big deal.
>
>
> It is a C++ design objective to leave no room for a lower level language,
> other than assembler. Do you think your request for defined orders of
> evaluation is compatible with that design objective? Or do you think the
> objective should be dropped now?
I think the request is compatible with that design objective. Like I
said before, optimizers often ignore sequence points if they can
conclude or assume the optimized code has the same results. I think the
statu quo is a mistake because of another design objective: have a
multi-platform language. How can a language be the multi-platform is
this simple code produces different results depending on compiler:
string foo() { cout << "y"; return "z"; }
cout << "x" << foo();
Few days ago, a beginner post some code on fr.comp.lang.c++ (thread
"notation postfixee"), this is pretty wrong code, basically the
programmer didn't understand why these two pieces of code have a
different behaviour.
while ( leNom[k] != '\0' && k <= 25) {
laVille.NomVille[k] = toupper(leNom[k]);
k = k + 1 ;
}
while ( leNom[k] != '\0' && k <= 25) {
laVille.NomVille[k] = toupper(leNom[k++]);
}
The beginner received different answers. The first answer is from a
programmer who seems to think that the right side of the assignment is
executed first. Another answer talks about the undefined behaviour of
the assignment (let's forget the undefined behaviour of toupper).
Amusingly, the beginner answered that the first answer seems to him to
be the most logical. The first answer is also wrong, but I agree with
this programmer, it is the most logical, and I would hope we could not
talk about "undefined behaviour" during one week on this
more-for-beginners newsgroup (fr.comp.lang.c++).
Like others, I just want all the code I produce to have a defined and
intuitive behaviour. It removes some language gotchas and makes code
more portable and reproduceable. I really think it's worth the cost. I
think it is acceptable to put the burden on the optimizer in that case.
Regards,
Nicolas Fleury
---
[ 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 ]
Author: brangdon@cix.co.uk (Dave Harris)
Date: Mon, 21 Apr 2003 17:31:53 +0000 (UTC) Raw View
qrczak@knm.org.pl ("Marcin 'Qrczak' Kowalczyk") wrote (abridged):
> Well, assemblers have explicit order of evaluation, so I don't
> understand why you say it would make C++ too high level.
I had in mind D&E $4.5, where Stroustrup talks about C replacing higher
level languages where control or speed is deemed essential. He wanted C++
to be able to avoid that.
He mentions that C++ primitive operations and data types should be
mappable on to hardware in one-to-one fashion. If, for example, C++ were
to specify an order for evaluating function operands, and the local O/S
calling convention specifies data be pushed onto a stack in a different
order, then a compiler would need to juggle the parameters around to match
the orders up. A C compiler would not need to do that so would be more
efficient for the same source code.
Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
brangdon@cix.co.uk | And close your eyes with holy dread,
| For he on honey dew hath fed
http://www.bhresearch.co.uk/ | And drunk the milk of Paradise."
---
[ 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 ]
Author: witoldk@optonline.net (witoldk)
Date: Thu, 17 Apr 2003 17:45:49 +0000 (UTC) Raw View
allan_w@my-dejanews.com (Allan W) wrote in message news:<7f2735a5.0304041340.5aedbd14@posting.google.com>...
> witoldk@optonline.net (witoldk) wrote
[snip]
> > Furthermore, where gains like that matter,
> > C++, being the general-purpose language might not be the best
> > tool to do the job.
>
> People often get the best of all worlds by combining C++ with
> assembly language. Most of the program would be in C++, but the
> sections with critical timing would be written in assembly
> language.
My point, exactly.
> Also, sometimes the only way to make these low-level optimizations
> is trial and error. Which is faster:
>
> // #1
> double sum(double ary[], int size) {
> assert(size>0);
> double result=ary[0];
> for (int i=1; i<size; ++i) result += ary[i];
> return result;
> }
>
> // #2
> double sum(double *ary, int size) {
> assert(size>0);
> double result=*ary;
> while (--size) result += *++ary;
> return result;
> }
>
> I hope you answered, "the only way to tell is to try them both."
Sorry, my answer was: I am not going to invest any time trying to see.
That is because it has been many years since I've noticed, that with
the code like that the comiler does quite a good job, regardless of
how I write down my intentions.
> This only touches on the issue of optimization. There ought to be
> a 15-week college class on the topic (does anyone know of a
> college that actually does this?).
How many weeks, you think, could be slashed from the class had the
order of evaluation been fully specified?
---
[ 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 ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Fri, 18 Apr 2003 00:01:39 +0000 (UTC) Raw View
> allan_w@my-dejanews.com (Allan W) wrote
> > This only touches on the issue of optimization. There ought to be
> > a 15-week college class on the topic (does anyone know of a
> > college that actually does this?).
witoldk@optonline.net (witoldk) wrote
> How many weeks, you think, could be slashed from the class had the
> order of evaluation been fully specified?
Could slash even more time, by teaching LOGO instead of C++.
Is this sufficient motivatin to rip all of the non-LOGO features out
of C++?
If all you need is turtle-graphics, LOGO is the way to go.
---
[ 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 ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Fri, 18 Apr 2003 00:02:23 +0000 (UTC) Raw View
nid_oizo@yahoo.com_removethe_ (Nicolas Fleury) wrote
> Yes, a Java-like
> execution order will reduce optimizations, but how much?
...
> What I
> would like to see is concrete performance numbers with real applications
> compiled, with and without the related optimizations.
You keep saying that, as if the number was on page 217 of "The big secret
book of optimization costs." In fact, making this type of measurement is
a Big Deal(tm).
I highly suggest that you try it yourself. Download G++ source code,
then modify it to order evaluations the same way that Java does. Be sure
to remove any optimizations that prohibit this type of reordering.
Compile and test your mods, until you're sure that (other than defining
the order of operations) it still works identically to the first version.
Then do some timing tests and report back here.
Go ahead.
I'll wait.
Go ahead! I'm waiting.
I'll just wait over here...
---
[ 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 ]
Author: witoldk@optonline.net (witoldk)
Date: Fri, 18 Apr 2003 16:58:58 +0000 (UTC) Raw View
allan_w@my-dejanews.com (Allan W) wrote in message news:<7f2735a5.0304171534.88831b3@posting.google.com>...
> > allan_w@my-dejanews.com (Allan W) wrote
> > > This only touches on the issue of optimization. There ought to be
> > > a 15-week college class on the topic (does anyone know of a
> > > college that actually does this?).
>
> witoldk@optonline.net (witoldk) wrote
> > How many weeks, you think, could be slashed from the class had the
> > order of evaluation been fully specified?
>
> Could slash even more time, by teaching LOGO instead of C++.
>
Funny, first you answer two rhetorical questions taking more
that 50 lines of text.
Then you completely miss the point of a third. The question you
answered above is also of rhetorical kind. I thought the answer
was obvious: had the eval order been fully specified, you could
slash zero weeks.
---
[ 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 ]
Author: kanze@gabi-soft.de (James Kanze)
Date: Wed, 23 Apr 2003 16:37:55 +0000 (UTC) Raw View
brangdon@cix.co.uk (Dave Harris) wrote in message
news:<memo.20030421174137.52913C@brangdon.madasafish.com>...
> qrczak@knm.org.pl ("Marcin 'Qrczak' Kowalczyk") wrote (abridged):
> > Well, assemblers have explicit order of evaluation, so I don't
> > understand why you say it would make C++ too high level.
> I had in mind D&E $4.5, where Stroustrup talks about C replacing
> higher level languages where control or speed is deemed essential. He
> wanted C++ to be able to avoid that.
> He mentions that C++ primitive operations and data types should be
> mappable on to hardware in one-to-one fashion. If, for example, C++
> were to specify an order for evaluating function operands, and the
> local O/S calling convention specifies data be pushed onto a stack in
> a different order, then a compiler would need to juggle the parameters
> around to match the orders up. A C compiler would not need to do that
> so would be more efficient for the same source code.
The question is: would it? Or more concretely, are there platforms
where it would make a difference. I'm currently working on a Sun
Sparc, where it almost certainly wouldn't. The situation for an Intel
architecture is not quite the same, however, although I don't think it
could make a measurable difference there : the difference would be on
the order of one more instruction, and if the expressions were simple
enough for that to make a difference, they would also be simple enough
for the compiler to reorder under the as-if rule as well.
The fact remains that it is a very difficult to really know. It's easy
to give bad faith answers -- defying someone prove it doesn't make a
difference by modifying g++ to respect the rules (actually a bad choice,
because g++ doesn't do much reordering anyway, at least not on Sparc),
or pointing out benchmarks where Java is faster than C++, despite
reordering.
The issues have changed since C estabilished the rule. Twenty years
ago, using Sethi-Ulmann numbers was enough to put you at the leading
edge of optimization technology (to use Sethi-Ulmann numbers, you need
the freedom to rearrange), and many of the most frequently used machines
had as little as eight registers. Today, compilers are able to analyse
far deeper -- and have to, in order to handle scheduling issues that
didn't exist before. And with the exception of one major architecture,
register presure is greatly reduced. IF reordering will make a
difference (and I'm not really convinced), then it will be because of
scheduling issues like those Ron pointed out, and not because
Sethi-Ulmann numbers say to evaluate one side before the other -- I
suspect that even on an Intel architecture, this will be true, although
with only 8 registers (6 useful), the issue is less clear.
And I repeat, the issue isn't whether it is possible to generate cases
where a fixed order will require one extra instruction. The question is
whether such cases actually occur in contexts where one extra
instruction would make a measurable differences. The obvious cases
involve function calls to other modules when evaluating the parameters,
so that the compiler cannot do any effective as-if evaluation, but the
function call alone will typically take ten times the time of the extra
instruction.
--
James Kanze GABI Software mailto:kanze@gabi-soft.fr
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, T l. : +33 (0)1 30 23 45 16
---
[ 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 ]
Author: nid_oizo@yahoo.com_removethe_ (Nicolas Fleury)
Date: Thu, 3 Apr 2003 18:53:59 +0000 (UTC) Raw View
Hyman Rosen wrote:
> Allan W wrote:
>
>> So, why wouldn't Nicolas's wording do what he wants?
>
>
> Compare 1.9/17 (function call) vs. 1.9/18 (ordered operators).
>
> For real amusement, check footnote 12 of 1.9/18, which points
> out that 'a, b' has a sequence point after a is evaluated only
> for built-in operator, but not for user-defined operator, !
> If that isn't a sign of woeful and misguided design, I don't
> know what is.
Don't you think this woeful and misguided design should be corrected?
The simpler and backward-compatible way wouldn't be to make ',' to
introduces sequence points everywhere, when it's a built-in operator,
when it's a user-defined operator and when it's a separator?
Are you saying that 1.9/17-18 justifies the statu quo?, 'cause I don't
see it. I see in 1.9/17-18 what I think should be changed to make C++
more predictable and intuitive; I mostly care about the ',' separator
behaviour. There's also the operator<< and operator>>, but since they
are not only used by the io streams, in which design may suggest to
programers execution order, I guess it's more debatable.
Regards,
Nicolas Fleury
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 3 Apr 2003 18:07:25 +0000 (UTC) Raw View
Allan W wrote:
> So, why wouldn't Nicolas's wording do what he wants?
Compare 1.9/17 (function call) vs. 1.9/18 (ordered operators).
For real amusement, check footnote 12 of 1.9/18, which points
out that 'a, b' has a sequence point after a is evaluated only
for built-in operator, but not for user-defined operator, !
If that isn't a sign of woeful and misguided design, I don't
know what is.
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 3 Apr 2003 21:29:08 +0000 (UTC) Raw View
Nicolas Fleury wrote:
> Don't you think this woeful and misguided design should be corrected?
Yes.
> The simpler and backward-compatible way wouldn't be to make ',' to
> introduces sequence points everywhere, when it's a built-in operator,
> when it's a user-defined operator and when it's a separator?
There are no backward-compatibility issues at all, since the
current behavior is either unspecified or undefined depending
on the expression. The best way to fix the problem is to fully
define order of evaluation, so that expressions are portable
and mean the same thing everywhere. If you want to just make
each argument in a function call be fully evaluated before any
other argument begins its evaluation, it's possible to do that
but it takes more than your one-liner to define that behavior.
> Are you saying that 1.9/17-18 justifies the statu quo?, 'cause I don't
> see it. I see in 1.9/17-18 what I think should be changed to make C++
> more predictable and intuitive; I mostly care about the ',' separator
> behaviour. There's also the operator<< and operator>>, but since they
> are not only used by the io streams, in which design may suggest to
> programers execution order, I guess it's more debatable.
The status quo is completely unjustifiable. For the sake of a
handful of obscure potential optimizations, programmers have had
to live with decades of stupid gotchas, made even worse by C++.
I'm no big fan of Java, but this is one case where they absolutely
got it right.
---
[ 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 ]
Author: witoldk@optonline.net (witoldk)
Date: Fri, 4 Apr 2003 11:23:32 +0000 (UTC) Raw View
hyrosen@mail.com (Hyman Rosen) wrote in message news:<0pPia.6717$fE.3685@nwrdny02.gnilink.net>...
> Allan W wrote:
> > If the compiler knows how to generate code that evaluates
> > auto_ptr<X>(new X)
> > at the very same time that it also evaluates
> > auto_ptr<Y>(new Y)
>
> then it still isn't allowed to do it, because the Standard
> forbids interleaving execution of function calls. Unless it
> could do it as-if it was sequential. Which it can do anyway.
> And worrying about pessimization of non-existent computers
> to the detriment of existing programmers is less than useful.
Have been watching this fascinating discussion with at least
a bit of disbelief:) I've decided to add my 2c despite the
fact that my 2c are mostly philosophical in nature (as is the
whole issue, is it not?).
I believe I've seen somebody offering this view on another NG:
"What *I'm* telling you is that C++ and its makers have chosen
the lack or predictability in favor of the optimization."
Realizing the fact, I'm afraid it might be kinda hard to turn
things around _now_. That does not at all mean one should not
try :)
So far in the discussion, I've seen just one argument against
trying to have it (the order) specified: possible optimization
leading to some speed gains in the resulting code.
This argument seems weak. First, the speed gains cannot
reasonably be relied upon, because different compilers might
optimize the code in different ways. Second, I find it hard
to understand how _possible_ gains could be relevant for any
design. Third, a task, where speed gains realized by letting
the compiler optimize the code taking advantage of unspecified
order of evaluation might be tied to the particular compiler,
and/or hardware co closely, that it makes it irrelevant as
a case in general. Furthermore, where gains like that matter,
C++, being the general-purpose language might not be the best
tool to do the job. Based on my experience, speed gains like
that, if at all relevant, are noticeable only for very short
period of time anyway. Even more importantly, is it not the
prevailing opinion that the "speed" of any particular piece
of code is of minor importance as compared with other issues
(correctness, maintainability...)? Is it also not that the
most common advice for speed gains is the algorithm change
and not the existing code optimization for speed?
I believe that making the order specified would not really hurt
anything, as whatever the specification might be, it would still
be one of the orders possible today. Then, having the order
specified could greatly benefit everybody. I'm going to offer
another quote to make my point:
"
I suppose it is just a philosophical point of view, but I still think
that a properly specified language should give deterministic results
even for "badly-designed" code.
"
Even though the "badly-designed" part does not quite apply here,
the main point is of paramount importance. The properly specified
language should give deterministic results. Period.
Making the language specification more "proper" by specifying the
order of evaluation might inconvenience the compiler writers
somewhat, but it would greatly benefit the language end-users.
Now, is somebody going to write-up the proposal? :)
---
[ 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 ]
Author: nid_oizo@yahoo.com_removethe_ (Nicolas Fleury)
Date: Fri, 4 Apr 2003 11:30:00 +0000 (UTC) Raw View
Hyman Rosen wrote:
> Nicolas Fleury wrote:
>
>> Don't you think this woeful and misguided design should be corrected?
>
>
> Yes.
>
>> The simpler and backward-compatible way wouldn't be to make ',' to
>> introduces sequence points everywhere, when it's a built-in operator,
>> when it's a user-defined operator and when it's a separator?
>
>
> There are no backward-compatibility issues at all, since the
> current behavior is either unspecified or undefined depending
> on the expression. The best way to fix the problem is to fully
> define order of evaluation, so that expressions are portable
> and mean the same thing everywhere. If you want to just make
> each argument in a function call be fully evaluated before any
> other argument begins its evaluation, it's possible to do that
> but it takes more than your one-liner to define that behavior.
>
>> Are you saying that 1.9/17-18 justifies the statu quo?, 'cause I don't
>> see it. I see in 1.9/17-18 what I think should be changed to make C++
>> more predictable and intuitive; I mostly care about the ',' separator
>> behaviour. There's also the operator<< and operator>>, but since they
>> are not only used by the io streams, in which design may suggest to
>> programers execution order, I guess it's more debatable.
>
> The status quo is completely unjustifiable. For the sake of a
> handful of obscure potential optimizations, programmers have had
> to live with decades of stupid gotchas, made even worse by C++.
> I'm no big fan of Java, but this is one case where they absolutely
> got it right.
Could not agree more. Has a proposal been made for that? I would have
though so, since it's been a while Herb Sutter pointed it in GotW. I'm
fine with the java execution order, since I prefer to lose few
milliseconds in execution than waste hours programming and debugging
(and I'm not exagerating, I've waste time two times in unit tests with
that stuff). I was just proposing a ',' only rule as a compromise, but
I would prefer a Java-like solution.
Is there any C++ compiler supporting a Java-like execution order? That
could be useful to have an idea of the sacrified optimizations...
Regards,
Nicolas Fleury
---
[ 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 ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Sat, 5 Apr 2003 04:17:51 +0000 (UTC) Raw View
witoldk@optonline.net (witoldk) wrote
> So far in the discussion, I've seen just one argument against
> trying to have it (the order) specified: possible optimization
> leading to some speed gains in the resulting code.
> This argument seems weak. First, the speed gains cannot
> reasonably be relied upon, because different compilers might
> optimize the code in different ways.
> Third, a task, where speed gains realized by letting
> the compiler optimize the code taking advantage of unspecified
> order of evaluation might be tied to the particular compiler,
> and/or hardware co closely, that it makes it irrelevant as
> a case in general.
That's exactly the point of letting the compiler do the low-level
optimization. When you hand-optimize code, even if you do get it
right for one platform, it may very well have the exact opposite
results on a different platform. By contrast, compilers generally
know the platform you will be using, and how to optimize for it.
> Furthermore, where gains like that matter,
> C++, being the general-purpose language might not be the best
> tool to do the job.
C++ is supposed to be multi-paradigm. It's been billed as the
lowest-level high-level language. It's high-level for business
applications, but low-level for device drivers and other
components of operating systems.
People often get the best of all worlds by combining C++ with
assembly language. Most of the program would be in C++, but the
sections with critical timing would be written in assembly
language.
> Even more importantly, is it not the
> prevailing opinion that the "speed" of any particular piece
> of code is of minor importance as compared with other issues
> (correctness, maintainability...)?
It depends on the application. Non-interactive business applications
usually are not terribly sensitive to speed -- whether the program
takes 5 minutes or 15 won't make any difference during a nightly
cycle. At the other end of the spectrum, "real-time" programs
often have a fixed window of time to respond to events, or else they
will lose data. Even for devices that buffer the data, quick response
might make the difference between optimal throughput and poor
performance. For instance, the device driver for a "streaming" tape
drive must supply each block of data within some amount of time after
it's requested (it's been a few years, but I think it was on the
order of 80 milliseconds) or else the tape drive will overshoot the
spot. Then it has to rewind a few inches to re-write the data, making
the tape drive work VERY slowly.
Even for programs that are not responding to "real-time" events,
any program that is interactive in nature is going to benefit to
some degree by making it work quickly. I once used an unoptimized
text editor where there was a visual time lapse between pressing
a key and seeing it show up on the screen. Unless you've experienced
this, you cannot imagine how frustrating it was. The program
properly handled "type-ahead," so there was no real limit on how
quickly I could type. But the visual feedback was extremely
disorienting. I found that in order to type at anywhere near full
speed, I had to deliberately avoid looking at the screen. Even then,
if I ever typed a letter wrong and had to press the backspace key,
it was important to wait a few seconds before continuing, so that I
could see what was really going on.
> Is it also not that the
> most common advice for speed gains is the algorithm change
> and not the existing code optimization for speed?
Usually. That's why the first step in optimization is to look at the
algorithm, not the individual line items. But eventually there comes
a time when the overall algorithm is as tight as you know how to make
it. That's when it's time to break out the code profiler, and if it
doesn't make any high-level optimizations obvious, you must instead
look for low-level optimizations.
Also, sometimes the only way to make these low-level optimizations
is trial and error. Which is faster:
// #1
double sum(double ary[], int size) {
assert(size>0);
double result=ary[0];
for (int i=1; i<size; ++i) result += ary[i];
return result;
}
// #2
double sum(double *ary, int size) {
assert(size>0);
double result=*ary;
while (--size) result += *++ary;
return result;
}
I hope you answered, "the only way to tell is to try them both."
Furthermore, the one that's fastest on platform A might not be
the one that's fastest on platform B.
And then of course you also try variations such as loop unrolling.
What's the optimal amount of unrolling to do? It depends not only
on the processor and the size of it's instruction cache, but also
on the type of data typically passed in. Once again, you're left
with trying a change and profiling it to see what happens.
This only touches on the issue of optimization. There ought to be
a 15-week college class on the topic (does anyone know of a
college that actually does this?). But back to the main topic,
the fact is that some of the really good compilers will do some
of this for you. But the more you force them to conform to specific
order-of-evaluation, the less freedom you give the compilers to
do so.
---
[ 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 ]
Author: nid_oizo@yahoo.com_removethe_ (Nicolas Fleury)
Date: Sun, 6 Apr 2003 21:31:44 +0000 (UTC) Raw View
Allan W wrote:
> This only touches on the issue of optimization. There ought to be
> a 15-week college class on the topic (does anyone know of a
> college that actually does this?). But back to the main topic,
> the fact is that some of the really good compilers will do some
> of this for you. But the more you force them to conform to specific
> order-of-evaluation, the less freedom you give the compilers to
> do so.
Yes, but optmizers can also ignore sequence points if they can conclude
or assume it has no effect on execution results. Yes, a Java-like
execution order will reduce optimizations, but how much? That's the
question to me. Like others, I have the feeling the cost in performance
for a Java-like execution order could be really affordable. I would not
be surprised that some compilers use a Java-like execution order anyway,
because a majority of their clients wouldn't know these issues. What I
would like to see is concrete performance numbers with real applications
compiled, with and without the related optimizations. I think the statu
quo should be justified by something else than "if not it might affect
optimizations"; I think we all agree it affects performance. We are
arguing if the cost of Java-like execution order is bigger or not than
the cost of the statu quo "gotcha". The problem is that we have no
numbers to objectively evaluate the statu quo. I have no idea how much
I gain in performance from the undefined execution order, but I know
what I lost.
Regards,
Nicolas Fleury
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Mon, 24 Mar 2003 23:30:51 +0000 (UTC) Raw View
Allan W wrote:
> Furthermore, I suspect that the differences you are talking about
> are fundamental to the code generator
This has absolutely nothing to do with a code generator.
The compiler already knows how to deal with things that
must be done in order; adding a few others would be easy,
and would just be part of the semantic analysis. (For
example, there is already a sequence point after each
member and base of a class is initialized. This
struct a { int x, y; a(int &i) : x(i++), y(i++) { } };
is perfectly valid C++.)
---
[ 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 ]
Author: francis.glassborow@ntlworld.com (Francis Glassborow)
Date: Mon, 24 Mar 2003 23:31:21 +0000 (UTC) Raw View
In article <zaefa.79763$gi1.43104@nwrdny02.gnilink.net>, Hyman Rosen
<hyrosen@mail.com> writes
>And yet, we have short-circuit operators - &&, ||, and ?: - which
>force an evaluation order even though I'm sure there's at least ONE
>compiler out there that could do a better job if it was allowed to
>evaluate the subexpressions in a different order. After all, if you
>need a certain order, you could just write it explicitly.
No way. Those are examples of cases where specified ordering is
essential to provide the required semantics.
--
ACCU Spring Conference 2003 April 2-5
The Conference you cannot afford to miss
Check the details: http://www.accuconference.co.uk/
Francis Glassborow ACCU
---
[ 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 ]
Author: gdr@integrable-solutions.net (Gabriel Dos Reis)
Date: Tue, 25 Mar 2003 17:36:28 +0000 (UTC) Raw View
hyrosen@mail.com (Hyman Rosen) writes:
| When the constructor of a class object runs, there is a well-defined
| order for the construction of the subobjects, even if in your code
| you appear to call their constructors in a different order.
And I tend to consider the last part of your sentence a "mis-feature".
struct X {
int a;
int b;
X(int t) : b(t), a(b) { }
};
Ideally, this should be a "type-check error". Yes, I know, a cure
might be not to initialize data members with values depending on other
members. Alas, in practice, that is not so. And making the strict
observance of the order part of the "type system" may help catch those
non-determinisms.
Now, I would like to konw how important is the contruction
f(auto_ptr<X>(new X), auto_ptr<Y>(new Y))
in practice.
[Yes, I'm aware of the theoretical discussion. I'm asking for a
practical situation.]
--
Gabriel Dos Reis, gdr@integrable-solutions.net
---
[ 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 ]
Author: comp.std.c++_2003-03-25@nmhq.net (Niklas Matthies)
Date: Tue, 25 Mar 2003 17:36:48 +0000 (UTC) Raw View
On 2003-03-24 23:28, Francis Glassborow wrote:
> Hyman Rosen <hyrosen@mail.com> writes
>>Francis Glassborow wrote:
>>> And my point is exactly that using restrict adds nothing other than
>>> permission for the compiler to assume that none of the pointers are
>>> based on each other.
>>
>>And *my* point is that once the compiler knows this, it is free
>>to reorder the write-back just like it can do now, becuase ++*y
>>is known not to affect *x and *z.
>
> It knows no such thing, all it 'knows' is that the writer of the
> function says this is true, but the caller may not abide by that.
I just posted an "assume(condition)" macro on comp.std.c (please
see there) which allows compilers to use any programmer-specified
assumption to perform optimzations.
This means that even if some total order of evaluation was required,
we have already the means today to tell the compiler in performance-
critical cases that it may relax that order due to non-aliasing.
void f(int * x, int * y, int *z)
{
assume(x != y);
assume(y != z);
*x = ++*y + *z; // can be optimized now due to the assumptions given
}
The only thing that we need now is compilers that recognize the idiom
that the macro uses (if they do not already).
-- Niklas Matthies
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Tue, 25 Mar 2003 19:09:25 +0000 (UTC) Raw View
John Potter wrote:
> Then how do you assign to it?
You can't, in Java.
> I don't understand.
In "ordered-C++", the statement
++x %= n;
would work by incrementing x then modding it with n.
The statement
a[i++] += a[i];
would work by first computing both the lvalue and the rvalue
for the left-side a[i]. Then i would be incremented, and a[i]
(with the new value of i) would be added to the saved rvalue,
and stored in the saved lvalue. In written out form,
int *lv = &a[i];
int rv = *lv;
++i;
*lv = rv + a[i];
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Tue, 25 Mar 2003 19:30:24 +0000 (UTC) Raw View
Francis Glassborow wrote:
> No way. Those are examples of cases where specified ordering is
> essential to provide the required semantics.
Yes way. Who required those semantics? If those can be required,
why can't all ordering be required?
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Tue, 25 Mar 2003 19:30:24 +0000 (UTC) Raw View
Francis Glassborow wrote:
> It knows no such thing, all it 'knows' is that the writer of the
> function says this is true, but the caller may not abide by that.
Huh? What does that mean? How does the caller get to not abide by
that without writing erroneous code?
---
[ 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 ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: Tue, 25 Mar 2003 20:33:07 +0000 (UTC) Raw View
On Tue, 25 Mar 2003 19:09:25 +0000 (UTC), hyrosen@mail.com (Hyman Rosen)
wrote:
> In "ordered-C++", the statement
> ++x %= n;
> would work by incrementing x then modding it with n.
Looks like cwg issue 222 may produce exactly that.
> The statement
> a[i++] += a[i];
However, it does not look like it will change this. You say "i"
twice and ask for bad behavior. Using prefix would not change it.
John
---
[ 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 ]
Author: a9804814@unet.univie.ac.at (Thomas Mang)
Date: Tue, 25 Mar 2003 21:38:58 +0000 (UTC) Raw View
Gabriel Dos Reis schrieb:
>
>
> Now, I would like to konw how important is the contruction
>
> f(auto_ptr<X>(new X), auto_ptr<Y>(new Y))
>
> in practice.
> [Yes, I'm aware of the theoretical discussion. I'm asking for a
> practical situation.]
I have never written such code, but please note one can also turn your
question around:
How many practical situations could benefit (or even bugs that wouldn't be
bugs any more) from having more precisly defined evaluation order? And what
negative impact (especially on performance) would this have, and of what
practical use are these situations?
regards,
Thomas
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Tue, 25 Mar 2003 22:16:30 +0000 (UTC) Raw View
John Potter wrote:
> You say "i" twice and ask for bad behavior.
Well, I'm asking for it not to be bad behavior.
Order of evaluation is too important to be left to a whim :-)
---
[ 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 ]
Author: francis.glassborow@ntlworld.com (Francis Glassborow)
Date: Wed, 26 Mar 2003 00:41:58 +0000 (UTC) Raw View
In article <%8Ufa.1071$hB5.596@nwrdny02.gnilink.net>, Hyman Rosen
<hyrosen@mail.com> writes
>Francis Glassborow wrote:
>> No way. Those are examples of cases where specified ordering is
>>essential to provide the required semantics.
>
>Yes way. Who required those semantics? If those can be required,
>why can't all ordering be required?
Of course it could be, but the semantics of &&, || and ?: is exactly to
provide certain essential behaviour (that some expressions will not be
evaluated in certain situations. That allows certain idioms that are
useful. Left to right evaluation does not add anything helpful in an
environment where there are overloaded operators.
What should be evaluated left to right? Sub-expressions? What even if
the operators are left associative or have different precedence? Sorry,
I just do not see it. And I know the Java rule but it is a different
language without such things as overloaded operators.
--
ACCU Spring Conference 2003 April 2-5
The Conference you cannot afford to miss
Check the details: http://www.accuconference.co.uk/
Francis Glassborow ACCU
---
[ 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 ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Wed, 26 Mar 2003 18:21:01 +0000 (UTC) Raw View
hyrosen@mail.com (Hyman Rosen) wrote
> But C++ chooses other things in "lock-step".
> For example, if I say foo() + bar(), I know that either foo()
> or bar() must entirely complete before the other is called.
...but you don't know which one comes first. This is an excellent
example of what I mean by saying that it is NOT in lock-step.
The code is NOT forced to call them in any particular order
(left-to-right or right-to-left -- please see the subject line of
this thread!). Instead, it can do whichever it thinks will be faster,
or whichever makes the code generation easier, or whatever.
> When I initialize a class with bases and subobjects, I know in
> complete order how they will be initialized.
But here's a case where the ordering was neccesary to ensure
correct code. Bjarne, and later the standards committee, considered
these types of things very carefully. They specified it where it was
neccesary, and left it unspecified where it might matter.
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Wed, 26 Mar 2003 19:28:19 +0000 (UTC) Raw View
Allan W wrote:
> ...but you don't know which one comes first. This is an excellent
> example of what I mean by saying that it is NOT in lock-step.
> The code is NOT forced to call them in any particular order
> (left-to-right or right-to-left -- please see the subject line of
> this thread!). Instead, it can do whichever it thinks will be faster,
> or whichever makes the code generation easier, or whatever.
But it could be even more efficient and faster if the compiler was
allowed to execute statements fromm foo and bar in an interleaved
fashion, instead of forcing them to be sequential. If you don't want
that, it's no big deal to say
int i = foo();
i += bar();
After all, that's what you have to do with
baz(auto_ptr<X>(new X), auto_ptr<X>(new X));
> But here's a case where the ordering was neccesary to ensure
> correct code.
I don't see why. If function parameters can be initialized
in arbitrary order, why can't class members be the same?
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Wed, 26 Mar 2003 22:40:53 +0000 (UTC) Raw View
Francis Glassborow wrote:
> Left to right evaluation does not add anything helpful in an
> environment where there are overloaded operators.
I don't understand how overloaded operators enter into the
picture at all. But the Java rules applied to C++ would give
the same order of evaluation for both built-in and overloaded
operators.
> What should be evaluated left to right? Sub-expressions? What even if
> the operators are left associative or have different precedence? Sorry,
> I just do not see it. And I know the Java rule but it is a different
> language without such things as overloaded operators.
Again, I don't understand what overloading has to do with anything.
And neither does precedence or associativity. Given any binary operator,
the left operand is evaluated fully, and then the right operand is
evaluated fully. It's a nice, simple rule. You don't have to talk
about sequence points. A fertile area of undefinedness is eliminated.
It's chock full of orderly goodness. (Sorry - just watched Buffy :-)
---
[ 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 ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Thu, 27 Mar 2003 00:10:37 +0000 (UTC) Raw View
hyrosen@mail.com (Hyman Rosen) wrote
> > > But C++ chooses other things in "lock-step".
> > > For example, if I say foo() + bar(), I know that either foo()
> > > or bar() must entirely complete before the other is called.
> Allan W wrote:
> > ...but you don't know which one comes first. This is an excellent
> > example of what I mean by saying that it is NOT in lock-step.
> > The code is NOT forced to call them in any particular order
> > (left-to-right or right-to-left -- please see the subject line of
> > this thread!). Instead, it can do whichever it thinks will be faster,
> > or whichever makes the code generation easier, or whatever.
> But it could be even more efficient and faster if the compiler was
> allowed to execute statements fromm foo and bar in an interleaved
> fashion, instead of forcing them to be sequential.
That could indeed be faster, i.e. on a computer with multiple processors.
Unfortunately, the burden on programmers would be excessive. Imagine what
would happen if every program needed inter-process communication just to
access a global variable.
Contrast that to the burden of avoiding your earlier example:
a += (a=3); // You want this to be fully defined
To make it defined, simply say:
a=3; a+=a;
or whatever the heck you meant it to say. Simple.
My point is, there are times when the programmer does need "lock-step"
control over the order of execution, and there are other times we should
prefer to give the compiler freedom to rearrange things. The current
C++ standard reflects exactly that.
> > > When I initialize a class with bases and subobjects, I know in
> > > complete order how they will be initialized.
> > But here's a case where the ordering was neccesary to ensure
> > correct code.
>
> I don't see why. If function parameters can be initialized
> in arbitrary order, why can't class members be the same?
For the same reason we have constructors in the first place. If you
have a member
char*name;
you can't expect member functions to display the name properly if it
hasn't been completely constructed. In fact, you can't even expect
the program to detect the problem and say so -- name could contain
random gibberish, and dereferencing it could crash the program.
By the same token, some base class functions are public or protected.
If you're going to assume that the base is fully functional, first
you have to give it an opportunity to be completely initialized.
Imagine that we want to construct an ErrorMessage object, which on
GUI systems would display a window with an error message and wait
for the user to press OK. We want the message to be visible as soon
as it's constructed. But ErrorMessage can't ask the Window to draw
itself until the Window is fully constructed! So we would have to
say "wait for the constructor to finish." Or, maybe we could have
constructor phases: ErrorMessage would do the work in phase 2, on
the assumption that Window is fully constructed in phase 1. But
what happens if Window has it's own base class? Window might use
phase 2, so that ErrorMessage needs phase 3. Add another layer and
you see how silly this could get.
Then back up and think about what useful tasks ErrorMessage could
do before Window is fully constructed. Got a window title? You can't
modify the window to use it yet -- there might not be a window. All
you can do is save the parameter values to use AFTER the Window
has been fully constructed. Now you need some additional signal
(perhaps AfterConstructor) to tell us that now it's safe to use
that parameter. But this sounds a lot like a Phase 2 pass... we're
back where we started.
Force the base to completely construct before the derived class starts,
and the problem goes away. Now as soon as ErrorMessage's constructor
starts, it "knows" that we can do whatever is needed to the Window:
set the title, size, position, color, and text, and then make it visible.
As the French say, Violin!
---
[ 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 ]
Author: kanze@gabi-soft.de (James Kanze)
Date: Thu, 27 Mar 2003 22:42:25 +0000 (UTC) Raw View
ron@sensor.com ("Ron Natalie") wrote in message
news:<FKJea.67487$Ev6.45763@fe06.atl2.webusenet.com>...
> "James Kanze" <kanze@gabi-soft.de> wrote in message
> news:d6651fb6.0303210318.19ab1d2a@posting.google.com...
> > Having to write back to memory can be expensive. I agree. On some
> > machines (Intel or others with few registers), not being able to
> > reorder can be expensive. That's not my point. My point is that
> > the compiler can do it under the as if rule, and in the cases where
> > the compiler cannot, because of intervening function calls, etc.,
> > the difference ceases to be measurable, because they are negligible
> > compared to the function call (or whatever else prevents the
> > compiler from completing its analysis) its.
> No, the compiler can not do it as-if, it doesn't posess the necessary
> information to know.
The compiler posesses all of the information it wants. Most compilers
don't use all of it; the concept of "separate compilation" is often
taken too literally, for example. But the information is normally
there.
[...]
> > First, I'd like to thank you for the concrete example. For the
> > first time, I have something that I can really consider. I'm also
> > not familiar with the i860 architecture; the processors I'm familiar
> > with all have some sort of look-aside so that fetching a value just
> > written is particularly fast.
> You don't understand, it's not the fetching of the value just stored
> that is the problem. The problem is that to make it consistant in
> that general case, you must move the instructions around such that
> they are slower in the non-aliased case.
> > I'll have to think about it. I'm not convinced that such an
> > expression will occur in a critical loop in real code, without
> > something else also being present to limit it anyway.
> Really? This is EXACTLY the type of thing we do.
You write statements that aren't in a loop, or an enclosing function?
If this were the first instruction in a function, it is doubtable that
the compiler could advance the fetch anyway, since it can't move it out
of the function. And if it isn't, the compiler has some context on
which to judge what it might be able to do.
> > (I'd need to see the complete loop.) But I doubt we want to
> > eliminate it. It's something to consider when comparing against the
> > real benefits (with regards to exception safety, for example) of
> > defining ordering.
> How aboiut using the EXISTING LANGUAGE FEATURES?
You mean like restrict:-)?
> If you want or need a seqeunce point, put one in explicitly.
Your example is only a problem because of potential aliasing. Aliasing
that can hinder the optimizer in many other cases as well. In this
case, it doesn't hinder the optimizer because if there is aliasing,
there is undefined behavior; it is up to the user to ensure that no
aliasing occurs. But there are many other cases where aliasing is a
problem, even when there is no undefined behavior. For this reason, the
C committee introduced the keyword restrict, which sounds like exactly
what you need. Since it will even allow the optimization if the
expression is written in two separate statements.
It's fine to suggest putting in sequence points explicitly, but the
majority of programmers aren't up to it. And let's face it, when
exceptions are involved, sequence points are needed almost everywhere.
(I know, the obvious answer to that is to not use exceptions, since they
cause so many problems. Try arguing that point around here, though.)
So what you are saying is that 99% of the programmers around should run
risks they don't understand just so that the compiler can do a little
bit better with your particular code (and only in a few special cases),
when there is already an existing mechanism available in C which will
allow you to give the compiler the necessary information systematically
(regardless of whether one statement or two is involved). The mechanism
(restrict) is dangerous, but no more so than the undefined behavior.
And the average programmer doesn't have to use it -- it need only be
used when performance is critical, and presumably, you have people
involved how are qualified enough to use it.
--
James Kanze GABI Software mailto:kanze@gabi-soft.fr
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, T l. : +33 (0)1 30 23 45 16
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Fri, 21 Mar 2003 17:17:30 +0000 (UTC) Raw View
Ron Natalie wrote:
> This would BE a serious performance problem!
I don't understand why. It's got to get written back at
some point, so all you can claim is that writing it back
in a definite order is seriously worse than allowing the
compiler to choose. I don't believe it. Do you have any
evidence?
---
[ 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 ]
Author: gdr@integrable-solutions.net (Gabriel Dos Reis)
Date: Fri, 21 Mar 2003 17:17:51 +0000 (UTC) Raw View
hyrosen@mail.com (Hyman Rosen) writes:
| Gabriel Dos Reis wrote:
| > Well, if the purpose is not to have to worry about such expressions,
| > then it occurs to me that the least thing to do is leave their semantics
| > undefined.
|
| To "not worry" means that it will do what you expect,
Not really. Because you don't know what I expect.
| or at least not cause nasal demons.
Right now, I haven't been able to see any nasal demons. Did you?
| Undefined behavior
| is a specific problem for C++ because if it is ever
| encountered, you can no longer say anything about the
| behavior of the program.
I see undefined behaviour as a kind of type-check failure and if the
program fails to type-check I don't expect much from it. In fact, I
do not see what is so specific to C++ in "undefined behaviour".
--
Gabriel Dos Reis, gdr@integrable-solutions.net
---
[ 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 ]
Author: a9804814@unet.univie.ac.at (Thomas Mang)
Date: Fri, 21 Mar 2003 17:18:07 +0000 (UTC) Raw View
Thomas Mang schrieb:
> Hyman Rosen schrieb:
>
> > Leo wrote:
> > > Does anyone know why evaluating expressions from right to left is a
> > > sensible design choice in C++? Just to clarify: I'm not questioning if
> > > it does that. I know it does.
> >
> > You "know" incorrectly. In fact, order of evaluation is
> > unspecified, and the compiler is free to choose any order
> > it likes. In some cases, like your commented out statement,
> > you can cause undefined behavior if you modify an lvalue
> > twice without an intervening sequence point.
>
> Here I ask too:
>
> What advantage can compiler writers take off by resulting "x = ++x" in
> undefined behavior?
> Other languages clearly define this construct, C++ not. Is there any
> hard-fact reason to make this undefined?
>
> If I am not mistaken, this is also undefined, but is much more likely to
> happen in pracice than the expression above:
>
> int a = 0;
> int & b = a;
> a = ++b;
>
> Here, aliasing hides the fact that actually a is modified 2 times without
> sequence point between write - accesses.(Or am I totally wrong and the
> reference adds a sequence point??).
>
> It was/is quite popular to check in the assignment-operator against
> self-assignment before freeing ressources. However, I have never seen
> checking for aliasing in code such as the one above. Pitfall, isn't it ?
>
> best regards,
>
> Thomas
As the whole discussion became quite eloquently, I am proposing this:
Is it worth an idea to require implementations to support a compiler switch to
support both what we have today (for the sake of those who fear their programs
run too slow) and another mode without the whole sequence point stuff (for the
sake of those who simply want to write less error-pronce code, even if there
might be a performance loss)?
regards,
Thomas
---
[ 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 ]
Author: francis.glassborow@ntlworld.com (Francis Glassborow)
Date: Fri, 21 Mar 2003 18:55:56 +0000 (UTC) Raw View
In article <1048203490.593997@master.nyc.kbcfp.com>, Hyman Rosen
<hyrosen@mail.com> writes
>Francis Glassborow wrote:
>> All that the restrict qualifier does is to place the burden for not
>>aliasing onto the programmer, it does not place any requirement on the
>>compiler, on the contrary, its purpose is to allow the compiler to
>>make assumptions that it could not otherwise make.
>
>The piece of code in question was
> *x = ++*y + *z;
>The burden was already on the programmer, because if restrict
>does in fact not apply to y, then the behavior is undefined.
Iff y is aliased by either x or z. And my point is exactly that using
restrict adds nothing other than permission for the compiler to assume
that none of the pointers are based on each other. Note the term based,
which is more extensive than just being aliases which is the real
benefit provided by restrict because it allows the compiler to assume
that arrays are independent if they are written to which opens up a
whole new range of potential optimisations.
Actually restrict does have a small potential diagnostic potential for
ordinary aliasing:
void foo(int * restrict i_ptr, int * restrict j_ptr);
int * i_ptr;
...
foo(i_ptr, i_ptr);
Now the compiler can issue a warning, but I suspect that it cannot do
more unless it can demonstrate that both parameters are used and at
least one is used for writing. But I would have to spend time looking at
the exact restrictions provided by restrict to determine the correct
answer.
--
ACCU Spring Conference 2003 April 2-5
The Conference you cannot afford to miss
Check the details: http://www.accuconference.co.uk/
Francis Glassborow ACCU
---
[ 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 ]
Author: kanze@gabi-soft.de (James Kanze)
Date: Fri, 21 Mar 2003 18:55:59 +0000 (UTC) Raw View
francis.glassborow@ntlworld.com (Francis Glassborow) wrote in message
news:<E15gb0F5BYe+EwSd@robinton.demon.co.uk>...
> In article <traea.59244$68.58935@nwrdny01.gnilink.net>, Hyman Rosen
> <hyrosen@mail.com> writes
> >Ron Natalie wrote:
> >> If we wanted C++ to be as slow as Java, that would be fine.
> >Oh, now, this is completely disingenuous. You know as well as I that
> >speed differences between C++ and Java have nothing to do with order
> >of evaluation.
> You sure about that? The intention is that C++ is usable on a very
> wide range of hardware some of which could not support a JVM. Java is
> designed to run only on a Java machine or a JVM running on hardware
> that can support it.
> Consider:
> a=3;
> b=a;
> c=b+a;
> A strict interpretation of the Java rules requires that both b and a
> be fetched after the address of (lvalue) c has been evaluated. In C++
> this isn't even a theoretical problem because the compiler just codes
> use of what is already in registers.
Both languages have the "as if" rule, or its equivalent. The C/C++
defines the language in terms of an abstract machine, which does fetch
the two values from memory. There are intervening sequence points, so
the actual implementation is required to do this as well, just as in
Java. Modulo the as if rule, in the two cases.
This has nothing to do with what we are talking about. Consider rather
the following expression.
x = f() + g() ;
In Java, it is guaranteed that f() will be called before g(). In Java,
it is guaranteed that if g() throws, any side effects of f() will have
taken place. C++ doesn't have these guarantees. This becomes even more
of an issue if instead of f() and g(), we have more complex expressions
(which can be interleaved):
f( std::auto_ptr<X>( new X ), std::auto_ptr<Y>( new Y ) ) ;
As you know, the above code is not exception safe. You know it, but how
many average programmers know it? And why should we have to write
something more complex, when this is what we want?
--
James Kanze GABI Software mailto:kanze@gabi-soft.fr
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, T l. : +33 (0)1 30 23 45 16
---
[ 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 ]
Author: kanze@gabi-soft.de (James Kanze)
Date: Fri, 21 Mar 2003 18:56:26 +0000 (UTC) Raw View
ron@sensor.com ("Ron Natalie") wrote in message
news:<Ivoea.35974$VD2.34510@fe03.atl2.webusenet.com>...
> "James Kanze" <kanze@gabi-soft.de> wrote in message
> news:d6651fb6.0303200741.12ff756f@posting.google.com...
> > That's just an old wives tale. Can you show a case where it would
> > make a measurable difference, or are you just repeating the same old
> > fairy tale that you've heard elsewhere?
> It's not the order of operations, it's forcing the sequence point.
> Are you trying to show me that having to write back to memory
> prematurely is a feature that's not going to affect performance?
Having to write back to memory can be expensive. I agree. On some
machines (Intel or others with few registers), not being able to reorder
can be expensive. That's not my point. My point is that the compiler
can do it under the as if rule, and in the cases where the compiler
cannot, because of intervening function calls, etc., the difference
ceases to be measurable, because they are negligible compared to the
function call (or whatever else prevents the compiler from completing
its analysis) its.
> Have you ever worked with a good compiler (NOT GCC) on a machine where
> instruction scheduling is an issue? My specific experience with this
> is on the i860, but I suspect the same holds true for the SPARC and
> other RISC processors. The compiler reorders the loads and stores
> because by doing so avoids stalls in the various stages of the
> processor.
I am aware of this (although it would have been politer if you had said
a good optimizer -- GCC is a good compiler, globally, even if the
optimizer is shit).
> x = =++x is a trivial simplification. Lets try
> *x = ++ *y + *z'
> In order to make this consistant, you must force the value out to
> memory before *z is read. Memory loads aren't cheap operations. The
> 860 compiler would prefer to load *z as early as possible so that it
> will have arrived in the register before it is needed. The code would
> look something like:
> ld.l (r4), r6 // load *y
> ld.l (r5), r7 // load *z
> adds 1, r6, r6 // incr temporary copy of *y
> st.l r6, (r4) // store back...could happen at any time before seq pt., but now is good.
> adds r6, r7, r8 // add
> st.l r7, (r8)
> In order to do what you are asking for it would need to do:
> ld.l (r4), r6 // load *y
> adds 1, r6, r6 // stall, r6 not read yet.
> st.l r6, (r4)
> ld.l (r5), r7 // load *z
> adds r5, r7, r8 // stall, r7 not here yet.
> st.l r7, (r8)
First, I'd like to thank you for the concrete example. For the first
time, I have something that I can really consider. I'm also not
familiar with the i860 architecture; the processors I'm familiar with
all have some sort of look-aside so that fetching a value just written
is particularly fast.
I have seen compilers which could handle this; that could determine that
y and z could not be aliases for the same thing, and could thus advance
the load. Such technology isn't very frequent however, and requires a
great deal of resources itself. I don't think we can impose this sort
of technology just yet.
I'll have to think about it. I'm not convinced that such an expression
will occur in a critical loop in real code, without something else also
being present to limit it anyway. (I'd need to see the complete loop.)
But I doubt we want to eliminate it. It's something to consider when
comparing against the real benefits (with regards to exception safety,
for example) of defining ordering.
> > (And by the way, I've got benchmarks where Java is *faster* than
> > C++. All you need is a lot of array accesses -- C/C++'s aliasing
> > literally shuts down the optimizer.)
> Just goes to show you can write bad code in any language.
The C++ code wasn't bad. It's just that all of the implicit conversions
of arrays to pointers results in excessive aliasing. Anytime you throw
out information, you are making the job harder for the optimizer.
Sometimes, it can regenerate the information; in typical cases with
arrays in C/C++ code, such regeneration requires analysis of the all of
the call sites of the function. Something most current compilers don't
do.
> I'm busy here writing code that has to get specific work done in a
> small number of milliseconds. Java and C++ are different languages.
> There's little need to Javify C++ if it means losing the performance
> aspects that make it attractive.
I agree that C++ should retain the ability to access low level aspects
of the machine. I'm not sure, however, that optimization should be the
role of the programmer; I'd rather see more progress in optimizers.
--
James Kanze GABI Software mailto:kanze@gabi-soft.fr
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, T l. : +33 (0)1 30 23 45 16
---
[ 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 ]
Author: Bart.van.Ingen.Schenau@ict.nl (Bart van Ingen Schenau)
Date: Fri, 21 Mar 2003 18:56:39 +0000 (UTC) Raw View
On Thu, 20 Mar 2003 21:57:46 +0000 (UTC), go_go_sonic@hotmail.com
("chris jefferson") wrote:
>
>""Ron Natalie"" <ron@sensor.com> wrote in message
>news:NVnea.32853$334.7290@fe05.atl2.webusenet.com...
>>
>> It's not a complexity issue, it's a performance issue. By mandating
>> that the side effect must always occur before the expression can
>> be further evaluated you introduce an inefficency that is not warranted
>> in the general case just to make this particular degenerate case well
>> behaved.
>
>Any intellegant optimising compiler would be able to tell if it needed to
>add extra control points to deal with this problem if it was inserted into
>the standard. I'm certain it wouldn't slow things down in cases where the
>special case didn't come up.
And how would and intelligent compiler handle a function like this:
int foo(int& a, int&b)
{
return a++ + ++b;
}
Please note that it is unknown whether a and b are references to the
same or to different objects.
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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Fri, 21 Mar 2003 18:57:12 +0000 (UTC) Raw View
Thomas Mang wrote:
> Is it worth an idea to require implementations to support a compiler switch
No. Implementations can do as they please already.
There should be just one standard, specifying one behavior.
---
[ 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 ]
Author: kanze@gabi-soft.de (James Kanze)
Date: Fri, 21 Mar 2003 20:47:41 +0000 (UTC) Raw View
ron@sensor.com ("Ron Natalie") wrote in message
news:<SMqea.9584$Jj5.2944@fe07.atl2.webusenet.com>...
> "Hyman Rosen" <hyrosen@mail.com> wrote in message
> news:1048193281.527388@master.nyc.kbcfp.com...
> > Ron Natalie wrote:
> > > just to make this particular degenerate case well behaved.
> > The "non-degenerate" cases can pretty much work as before, since
> > those don't involve using and changing the same lvalue in a single
> > expression.
> You don't know if they are the same lvalue or not. You are asking for
> a goofy special case.
> > As I keep saying. I don't believe that requiring side-effects to
> > happen deterministically would have anything but the tiniest impact
> > on performance.
> You can keep saying that, but it doesn't make it true? Do you in fact
> have any experience with machine instruction level processor
> performance?
I do, and I've never been able to find a case where it would make a
difference. I've asked the question several times; before me, it was
David Chase (one of the top experts in optimization) who was asking it.
To date, no one has been able (or willing) to present a concrete case;
just a lot of hand waving.
--
James Kanze GABI Software mailto:kanze@gabi-soft.fr
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, T l. : +33 (0)1 30 23 45 16
---
[ 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 ]
Author: kanze@gabi-soft.de (James Kanze)
Date: Fri, 21 Mar 2003 20:48:08 +0000 (UTC) Raw View
comp.std.c++_2003-03-20@nmhq.net (Niklas Matthies) wrote in message
news:<slrnb7j0aj.2b0d.comp.std.c++_2003-03-20@nmhq.net>...
> On 2003-03-20 05:59, Gabriel Dos Reis <gdr@integrable-solutions.net>
> wrote:
> > hyrosen@mail.com (Hyman Rosen) writes:
> >| Andrew Koenig wrote:
> >| > What other languages define "x = ++x"?
> >| Java and C#. The left side is evaluated, and the lvalue is
> >| saved. The right side is evaluated, incrementing x. That rvalue is
> >| then stored in the saved lvalue (where it already is, in this
> >| case).
> >| Simple. Easy to explain. No sequence points needed. No undefined
> >| behavior. How nice if C++ had it.
> > What is the usefulness of such expression?
> To not have to worry about avoiding such expressions.
> Things can get non-obvious for example due to aliasing. Seemingly
> innocuous expressions like
> f(shared_ptr<X>(new X), G())
> would (supposedly) turn safe as well.
I think that this is the critical argument. Without deterministic
ordering, RAII simply doesn't work for anything but the simplest cases.
And without RAII, exceptions in C++ don't work. IMHA, it's rather
embarassing having to tell people that something like:
f( std::auto_ptr<X>( new X ), std::auto_ptr<Y>( new Y ) ) ;
is incorrect.
> The question should be: Are there expressions where performance would
> be significantly hurt by mandating a particular order of evaluation?
To date, no one has been able to show any cases where it would be.
--
James Kanze GABI Software mailto:kanze@gabi-soft.fr
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, T l. : +33 (0)1 30 23 45 16
---
[ 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 ]
Author: ron@sensor.com ("Ron Natalie")
Date: Fri, 21 Mar 2003 20:48:43 +0000 (UTC) Raw View
"Hyman Rosen" <hyrosen@mail.com> wrote in message news:1048204012.639585@master.nyc.kbcfp.com...
>
> > 3. There are more pressing issues with C++.
>
> Those aren't going to get done either.
>
Precisely my point.
---
[ 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 ]
Author: francis.glassborow@ntlworld.com (Francis Glassborow)
Date: Fri, 21 Mar 2003 20:49:00 +0000 (UTC) Raw View
In article <3E7A4C84.E9C5C00D@unet.univie.ac.at>, Thomas Mang
<a9804814@unet.univie.ac.at> writes
>As the whole discussion became quite eloquently, I am proposing this:
>
>Is it worth an idea to require implementations to support a compiler switch to
>support both what we have today (for the sake of those who fear their programs
>run too slow) and another mode without the whole sequence point stuff (for the
>sake of those who simply want to write less error-pronce code, even if there
>might be a performance loss)?
I doubt that such a requirement could be phrased in standard acceptable
terminology, and I I think that such a proposal would be rejected even
if it could be proposed.
--
ACCU Spring Conference 2003 April 2-5
The Conference you cannot afford to miss
Check the details: http://www.accuconference.co.uk/
Francis Glassborow ACCU
---
[ 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 ]
Author: llewelly.at@xmission.dot.com (LLeweLLyn)
Date: Fri, 21 Mar 2003 20:49:41 +0000 (UTC) Raw View
gdr@integrable-solutions.net (Gabriel Dos Reis) writes:
> hyrosen@mail.com (Hyman Rosen) writes:
>
> | Andrew Koenig wrote:
> | > What other languages define "x = ++x"?
> |
> | Java and C#. The left side is evaluated, and the
> | lvalue is saved. The right side is evaluated,
> | incrementing x. That rvalue is then stored in the
> | saved lvalue (where it already is, in this case).
> |
> | Simple. Easy to explain. No sequence points needed.
> | No undefined behavior. How nice if C++ had it.
>
> What is the usefulness of such expression?
>
> Personnaly, I would hate to see C++ actively support such codings.
[snip]
Personally, I would like to see C++ actively disown them (well, those
which already have undefined behavior, not those which are merely
unspecified), by requiring diagnostics for those which are readily
dectectable at compile time. I think this would eliminate most of
the disadvantages of the current ordering rules, and retain most
of the advantages, with little risk of breaking currently working
code (no risk of breaking conforming code).
I see the community heading this way in any case; some of those
constructs already evoke warnings from some compilers; people keep
asking for more such warnings. For C (but not C++ yet) gcc
already provides -Wsequence-point (See
gcc.gnu.org/onlinedocs/gcc-3.2.2/gcc/Warning-Options.html#Warning%20Options
and search for 'sequence'.)
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Fri, 21 Mar 2003 20:50:10 +0000 (UTC) Raw View
Francis Glassborow wrote:
> And my point is exactly that using restrict adds nothing other than
> permission for the compiler to assume that none of the pointers are
> based on each other.
And *my* point is that once the compiler knows this, it is free
to reorder the write-back just like it can do now, becuase ++*y
is known not to affect *x and *z.
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Fri, 21 Mar 2003 20:50:47 +0000 (UTC) Raw View
Bart van Ingen Schenau wrote:
> And how would and intelligent compiler handle a function like this:
> int foo(int& a, int&b)
> {
> return a++ + ++b;
> }
The increments of a and b must happen at some point,
so there is perhaps a tiny savings possible with
reordering, but not much, and would be entirely
overwhelmed by the overhead of the call itself. If
it's inlined, then the compiler will be able to see
whether the two references are to the same object,
and could do the increments out of order if they
are not.
---
[ 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 ]
Author: ron@sensor.com ("Ron Natalie")
Date: Fri, 21 Mar 2003 21:12:29 +0000 (UTC) Raw View
"James Kanze" <kanze@gabi-soft.de> wrote in message news:d6651fb6.0303210318.19ab1d2a@posting.google.com...
> Having to write back to memory can be expensive. I agree. On some
> machines (Intel or others with few registers), not being able to reorder
> can be expensive. That's not my point. My point is that the compiler
> can do it under the as if rule, and in the cases where the compiler
> cannot, because of intervening function calls, etc., the difference
> ceases to be measurable, because they are negligible compared to the
> function call (or whatever else prevents the compiler from completing
> its analysis) its.
No, the compiler can not do it as-if, it doesn't posess the necessary
information to know.
> I am aware of this (although it would have been politer if you had said
> a good optimizer -- GCC is a good compiler, globally, even if the
> optimizer is shit).
>
The perforamance as measured on the Pentiums and the sparc is lousy.
The code generator on the Pentium, which I have spent some time with,
is crappy. The language parser may be fine, but the code generation
on at least two of the major plaforms stucks. The generic code generator
(which they use for the Pentium, the platform I spent some time trying
to fix GCC for), is not adquate for all but the simplest of architectures.
It doesn't try to do any scheduling. Maybe you call that an optimization
problem, but the fact is that the compiler is just plain ignorant of any
concept of instruction scheduling.
> First, I'd like to thank you for the concrete example. For the first
> time, I have something that I can really consider. I'm also not
> familiar with the i860 architecture; the processors I'm familiar with
> all have some sort of look-aside so that fetching a value just written
> is particularly fast.
You don't understand, it's not the fetching of the value just stored
that is the problem. The problem is that to make it consistant
in that general case, you must move the instructions around such
that they are slower in the non-aliased case.
> I'll have to think about it. I'm not convinced that such an expression
> will occur in a critical loop in real code, without something else also
> being present to limit it anyway.
Really? This is EXACTLY the type of thing we do.
> (I'd need to see the complete loop.)
> But I doubt we want to eliminate it. It's something to consider when
> comparing against the real benefits (with regards to exception safety,
> for example) of defining ordering.
How aboiut using the EXISTING LANGUAGE FEATURES?
If you want or need a seqeunce point, put one in explicitly.
> I agree that C++ should retain the ability to access low level aspects
> of the machine. I'm not sure, however, that optimization should be the
> role of the programmer; I'd rather see more progress in optimizers.
>
Then don't restrict the freedom they have to do the right thing.
---
[ 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 ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Fri, 21 Mar 2003 23:27:04 +0000 (UTC) Raw View
hyrosen@mail.com (Hyman Rosen) writes:
> Bart van Ingen Schenau wrote:
>> And how would and intelligent compiler handle a function like this:
>> int foo(int& a, int&b)
>> {
>> return a++ + ++b;
>> }
>
> The increments of a and b must happen at some point,
> so there is perhaps a tiny savings possible with
> reordering, but not much, and would be entirely
> overwhelmed by the overhead of the call itself. If
> it's inlined, then the compiler will be able to see
> whether the two references are to the same object,
> and could do the increments out of order if they
> are not.
Not unless the variables are local to foo's caller, which is highly
unlikely for the caller of any function such as foo.
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
---
[ 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 ]
Author: francis.glassborow@ntlworld.com (Francis Glassborow)
Date: Fri, 21 Mar 2003 23:27:05 +0000 (UTC) Raw View
In article <m1wuitnmvg.fsf@localhost.localdomain>, LLeweLLyn
<llewelly.at@xmission.dot.com> writes
>Personally, I would like to see C++ actively disown them (well, those
> which already have undefined behavior, not those which are merely
> unspecified), by requiring diagnostics for those which are readily
> dectectable at compile time. I think this would eliminate most of
> the disadvantages of the current ordering rules, and retain most
> of the advantages, with little risk of breaking currently working
> code (no risk of breaking conforming code).
Now write a definition of 'readily detectable' that is capable of being
tested.
--
ACCU Spring Conference 2003 April 2-5
The Conference you cannot afford to miss
Check the details: http://www.accuconference.co.uk/
Francis Glassborow ACCU
---
[ 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 ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Sat, 22 Mar 2003 02:14:06 +0000 (UTC) Raw View
a9804814@unet.univie.ac.at (Thomas Mang) wrote
> As the whole discussion became quite eloquently, I am proposing this:
>
> Is it worth an idea to require implementations to support a compiler switch to
> support both what we have today (for the sake of those who fear their programs
> run too slow) and another mode without the whole sequence point stuff (for the
> sake of those who simply want to write less error-pronce code, even if there
> might be a performance loss)?
No.
C++ does nothing with "compiler switches."
Furthermore, I suspect that the differences you are talking about
are fundamental to the code generator, which is the most complicated
part of any compiler. If I'm right, then in essence, you would be
asking C++ compiler writers to write two compilers, and keep them,
in all respects save this one, 100% compatible. That's a heavy
burden.
---
[ 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 ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Sat, 22 Mar 2003 04:09:10 +0000 (UTC) Raw View
hyrosen@mail.com (Hyman Rosen) wrote
> Allan W wrote:
> > The C++ way
>
> In C++, the expression a += (a = 3) has undefined behavior.
> That you think it doesn't should tell you something about
> why the other way is better.
I didn't mean to imply that the behavior is defined, or that
it should be. I simply meant to explain WHY it's undefined;
the usual explanation is that the C++ compiler is free to use
optimizations appropriate for the current platform, which might
create problems if the code had to conform in lock-step to
some specific order (such as Java apparently has to).
> > Ignoring optimization
>
> Will give you large, slow code. So what?
Hmmph.
> // copy array[1..end] into array[0..end-1]
> i = 0; while (i < a.size() - 1) a[i++] = a[i];
Is undefined behavior. So what?
[I'm at least as good at ignoring context as you are!]
> >> 3) Function call arguments are evaluated left-to-right.
> >
> > By forcing us to evaluate arguments left-to-right the code is
> > bigger and slower.
>
> Again, this would matter only when more than one argument had
> side effects. And then, predictable behavior would be nice:
> printf("%d a %d b %d c", inc_id(), inc_id(), inc_id());
> cout << inc_id() << " a" << inc_id() << " b" << inc_id() << " c";
> How many people have been caught out on that last one?
No, more than one "argument" can have side effects without this
concern.
foo(i++, ++j, k=2);
Besides calling foo, we have 3 side-effects:
i is incremented (but the value before increment is passed to foo)
j is incremented (and the already-incremented value is passed to foo)
k is changed to 2 (and that value 2 is passed to foo)
The side-effects do not modify any variable more than once, and the
current value is used only to determine the new value for that
variable -- so this is completely legal.
foo(bar(1), bar(2), bar(3));
This too is legal. Bar will be called 3 times before foo is called.
We do NOT know if bar is called with 1 first, 2 first, or 3 first,
nor should we care. I suspect that machines which pass arguments
right-to-left, would call bar(3) first, and machines which pass
arguments left-to-right, would call bar(1) first -- but I refuse
to write code that depends on this assertion. If I need bar(1) to
be called first, there's no problem writing that explicitly:
{ int i=bar(1);
int j=bar(2);
int k=bar(3);
foo(i,j,k);
}
If C++ was constrained to evaluating arguments left to right,
then compiler would internally need to compile the code the same
way I've written it here -- so there's no loss. On many compilers
real the original version will compile the same way anyway, but
if ONE compiler does happen to figure out a way to generate
better-optimized code by evaluating arguments in some other order,
then the rule "evaluation order is unspecified" is a good one.
---
[ 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 ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Sat, 22 Mar 2003 04:09:20 +0000 (UTC) Raw View
hyrosen@mail.com (Hyman Rosen) wrote
> Ron Natalie wrote:
> > 2. It's slower.
>
> Quite arguable for the majority of cases, and a worthwhile
> tradeoff for the expressive benefit and lack of astonishment.
Read the C++ FAQ.
---
[ 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 ]
Author: a9804814@unet.univie.ac.at (Thomas Mang)
Date: Sat, 22 Mar 2003 19:15:10 +0000 (UTC) Raw View
Allan W schrieb:
> hyrosen@mail.com (Hyman Rosen) wrote
> >
> > Again, this would matter only when more than one argument had
> > side effects. And then, predictable behavior would be nice:
> > printf("%d a %d b %d c", inc_id(), inc_id(), inc_id());
> > cout << inc_id() << " a" << inc_id() << " b" << inc_id() << " c";
> > How many people have been caught out on that last one?
>
> No, more than one "argument" can have side effects without this
> concern.
>
> foo(i++, ++j, k=2);
>
> Besides calling foo, we have 3 side-effects:
> i is incremented (but the value before increment is passed to foo)
> j is incremented (and the already-incremented value is passed to foo)
> k is changed to 2 (and that value 2 is passed to foo)
> The side-effects do not modify any variable more than once, and the
> current value is used only to determine the new value for that
> variable -- so this is completely legal.
You forgot the potentiality for aliasing. It is defined (I am assuming i j
ank k are of built-in type - I guess your example assumed this too) iff i, j
and k are different objects.
In order to write it safe, code could look like this:
if (&i != &j && &i != &k && &j != &k)
foo(i++, ++j, k=2);
which is all but beautiful.
Sure, this is only an issue if references / dereferenced pointers are
involved - but then it gets, well, say "thin ice".
regards,
Thomas
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Sun, 23 Mar 2003 21:38:42 +0000 (UTC) Raw View
Allan W wrote:
> Read the C++ FAQ.
The C++ FAQ (Marshall Cline's, yes?) is quite large.
Perhaps you wish to direct my attention to a specific
portion?
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Sun, 23 Mar 2003 21:39:47 +0000 (UTC) Raw View
Allan W wrote:
> I simply meant to explain WHY it's undefined;
But C++ chooses other things in "lock-step".
For example, if I say foo() + bar(), I know that either foo()
or bar() must entirely complete before the other is called.
When I initialize a class with bases and subobjects, I know in
complete order how they will be initialized.
> Is undefined behavior. So what?
This is an exmaple (in Java, where it's perfectly well-defined)
for what it means for operands to be completely evaluated before
operators are applied.
> nor should we care
Why in the world shouldn't we care? I already gave good examples
(involving output) where we certainly do care. If I write
bar(1), bar(2), bar(3);
then it's OK to care, but if I write
foo(bar(1), bar(2), bar(3));
then it's not?
> there's no problem writing that explicitly
The point of C's increment and assignment expressions is to
increase the expressibility of expressions. Forcing explicit
and lengthy code is not in the spirit of C.
> if ONE compiler does happen to figure out a way to generate
> better-optimized code by evaluating arguments in some other order,
> then the rule "evaluation order is unspecified" is a good one.
And yet, we have short-circuit operators - &&, ||, and ?: - which
force an evaluation order even though I'm sure there's at least ONE
compiler out there that could do a better job if it was allowed to
evaluate the subexpressions in a different order. After all, if you
need a certain order, you could just write it explicitly.
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Mon, 24 Mar 2003 00:42:07 +0000 (UTC) Raw View
David Abrahams wrote:
> Not unless the variables are local to foo's caller, which is highly
> unlikely for the caller of any function such as foo.
Under current rules, foo would be undefined if a and b wrere aliasing
each other, so it's more than likely that when looked at in the context
of the caller, the compiler would see that they were not aliased.
Well, perhaps someone will take the initiative to give this a try in
gcc and see what happens. Part of the compiler already supports this,
since it can compile Java.
---
[ 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 ]
Author: ron@sensor.com ("Ron Natalie")
Date: Mon, 24 Mar 2003 23:24:26 +0000 (UTC) Raw View
"Hyman Rosen" <hyrosen@mail.com> wrote in message news:1048192933.654223@master.nyc.kbcfp.com...
> Ron Natalie wrote:
> > This would BE a serious performance problem!
>
> I don't understand why. It's got to get written back at
> some point, so all you can claim is that writing it back
> in a definite order is seriously worse than allowing the
> compiler to choose. I don't believe it. Do you have any
> evidence?
>
I posted the evidence. Specific examples from a specific compiler
which has had a C++ implementation on it. My assertion is that the
i860 I showed is not substantially different from other RISC processors
such as the Sparc.
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Mon, 24 Mar 2003 23:24:52 +0000 (UTC) Raw View
When the constructor of a class object runs, there is a well-defined
order for the construction of the subobjects, even if in your code
you appear to call their constructors in a different order.
Think about why this is so. For example, 12.9 of D&E says
"Leaving the initialization order unspecified in the original
definition of C++ gave an unnecessary degree of freedom to
language implementers at the expense of the users."
Exactly.
---
[ 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 ]
Author: francis.glassborow@ntlworld.com (Francis Glassborow)
Date: Mon, 24 Mar 2003 23:28:45 +0000 (UTC) Raw View
In article <1048274947.520249@master.nyc.kbcfp.com>, Hyman Rosen
<hyrosen@mail.com> writes
>Francis Glassborow wrote:
>> And my point is exactly that using restrict adds nothing other than
>> permission for the compiler to assume that none of the pointers are
>> based on each other.
>
>And *my* point is that once the compiler knows this, it is free
>to reorder the write-back just like it can do now, becuase ++*y
>is known not to affect *x and *z.
It knows no such thing, all it 'knows' is that the writer of the
function says this is true, but the caller may not abide by that.
--
ACCU Spring Conference 2003 April 2-5
The Conference you cannot afford to miss
Check the details: http://www.accuconference.co.uk/
Francis Glassborow ACCU
---
[ 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 ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: Mon, 24 Mar 2003 23:29:32 +0000 (UTC) Raw View
On Thu, 20 Mar 2003 21:56:58 +0000 (UTC), hyrosen@mail.com (Hyman Rosen)
wrote:
> John Potter wrote:
> > In C++, ++x is an lvalue. How does ++x %= n behave
> > in those other languages? A very useful expression
> > for circular buffers.
>
> It's not an lvalue in Java.
Then how do you assign to it?
> But the rule is left before
> right, operands before operation. So in your example, we
> evaluate ++x, applying the increment.
And get an rvalue? I repeat, how do you
> Then we do the %=.
> The result is as if you had said 'x = (x + 1) % n', except
> that you just have to name 'x' once.
I don't understand.
John
---
[ 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 ]
Author: kanze@alex.gabi-soft.fr (James Kanze)
Date: Mon, 31 Mar 2003 04:24:07 +0000 (UTC) Raw View
gdr@integrable-solutions.net (Gabriel Dos Reis) writes:
|> Now, I would like to konw how important is the contruction
|> f(auto_ptr<X>(new X), auto_ptr<Y>(new Y))
|> in practice.
|> [Yes, I'm aware of the theoretical discussion. I'm asking for a
|> practical situation.]=20
It's an interesting question. It's certainly not very frequent in the
code I've seen, because no one uses auto_ptr:-). Mais as a general
problem, I'm less certain, and similar idioms are bound to become more
frequent as people adopt smart pointers as a means of obtaining
exception safety.
It's worth pointing out that if this idiom was the object of a GotW,
it is largely because David Abrahams posted it as a solution to a
exception safety problem. And if David Abrahams was not aware of the
potential problem then, it seems like a fairly safe assumption that
many people are not aware of it today. Boost warns about it in their
documentation of shared_ptr, but how many people are using
boost::shared_ptr na=EFvely, without having studied the documentation?
Consider too that it makes programs more fragile. Consider the
following code:
f( boost::shared_ptr( new T() ), a + b ) ;
If a and b are ints or doubles, no problem, As the program evolves,
it turns out that int isn't big enough, and someone changes them to
BigInt, with an overloaded operator+ which allocates. Suddenly,
working code is broken.
--=20
James Kanze mailto:kanze@gabi-soft.fr
Conseils en informatique orient=E9e 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 ]
Author: nid_oizo@yahoo.com_removethe_ (Nicolas Fleury)
Date: Mon, 31 Mar 2003 19:00:13 +0000 (UTC) Raw View
Gabriel Dos Reis wrote:
> Now, I would like to konw how important is the contruction
>
> f(auto_ptr<X>(new X), auto_ptr<Y>(new Y))
>
> in practice.
> [Yes, I'm aware of the theoretical discussion. I'm asking for a
> practical situation.]
I expect stuff like boost::shared_ptr to be more and more used in
future. We can expect this kind of construction to be more frequent as
a generation of programers used with garbage-collected languages (and
Java looks like C++) participate in development of large C++
applications. I would expect smart pointers to be more and more used.
I would expect the use of exceptions to increase also.
The problem is how many C++ programers know the problem with the
construction, and of them, how many are able to justify this C++ design
to their colleagues? How much C++ programers gain in optimization? And
how much they might lose because they're not aware of the problem or
simply because they have to make a workaround for it?
Nicolas Fleury
---
[ 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 ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Tue, 1 Apr 2003 05:54:04 +0000 (UTC) Raw View
kanze@alex.gabi-soft.fr (James Kanze) writes:
> gdr@integrable-solutions.net (Gabriel Dos Reis) writes:
>
> |> Now, I would like to konw how important is the contruction
>
> |> f(auto_ptr<X>(new X), auto_ptr<Y>(new Y))
>
> |> in practice.
>
> |> [Yes, I'm aware of the theoretical discussion. I'm asking for a
> |> practical situation.]
>
> It's an interesting question. It's certainly not very frequent in the
> code I've seen, because no one uses auto_ptr:-). Mais as a general
> problem, I'm less certain, and similar idioms are bound to become more
> frequent as people adopt smart pointers as a means of obtaining
> exception safety.
>
> It's worth pointing out that if this idiom was the object of a GotW,
> it is largely because David Abrahams posted it as a solution to a
> exception safety problem.
IIRC it came up because I noticed the problem with sequence points
after writing some code like that, and the GotW happened because I
suggested that Herb run a GotW on that topic (you can look that one
up). But it doesn't gainsay your point that I had only just become
aware of the problem at the time.
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
---
[ 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 ]
Author: kanze@gabi-soft.de (James Kanze)
Date: Tue, 1 Apr 2003 18:47:33 +0000 (UTC) Raw View
dave@boost-consulting.com (David Abrahams) wrote in message
news:<uvfxz5o0n.fsf@boost-consulting.com>...
> kanze@alex.gabi-soft.fr (James Kanze) writes:
> > gdr@integrable-solutions.net (Gabriel Dos Reis) writes:
> > |> Now, I would like to konw how important is the contruction
> > |> f(auto_ptr<X>(new X), auto_ptr<Y>(new Y))
> > |> in practice.
> > |> [Yes, I'm aware of the theoretical discussion. I'm asking for a
> > |> practical situation.]
> > It's an interesting question. It's certainly not very frequent in
> > the code I've seen, because no one uses auto_ptr:-). Mais as a
> > general problem, I'm less certain, and similar idioms are bound to
> > become more frequent as people adopt smart pointers as a means of
> > obtaining exception safety.
> > It's worth pointing out that if this idiom was the object of a GotW,
> > it is largely because David Abrahams posted it as a solution to a
> > exception safety problem.
> IIRC it came up because I noticed the problem with sequence points
> after writing some code like that, and the GotW happened because I
> suggested that Herb run a GotW on that topic (you can look that one
> up). But it doesn't gainsay your point that I had only just become
> aware of the problem at the time.
The GofW is #56, May 23, 1999. According to the version on Herb's web
site, "This puzzle points out an exception safety problem that was
discovered only weeks before posting." He also credits you, me and
Steve Clamage as the people behind it.
My memory (admittedly often faulty) is that you posted an example with
this code, I pointed out that it wasn't guaranteed, and you answered
something to the effect of how right I was, and isn't that a surprise.
(I also have a sort of a memory that someone else had pointed the
problem out to me a good while before, and that I'd forgotten about it
until your posting triggered something in my memory.)
But I can't seem to find the thread on Google. I do find a thread very
shortly before Herb's GotW in which I point out the problem, but with
words staring "we had an obvious example just a little while ago". I'd
like to see the posting with the "obvious example" I was referring to,
but no matter what search critera I use, nothing seems to come up.
But it doesn't really matter. The point is that the problem wasn't
known, at least not to very many people, and that even today, it is
probable that the vast majority of programmers are not aware of it. And
it imposes alternative solutions which are not as "natural".
And the problem being discussed in this thread is indirectly related to
one Herb treated in a earlier GotW, #20. The question was, how many
execution paths are there in this simple, four line function. Herb
found 23, but "different orders of evaluating function parameters and
exceptions thrown by destructors are ignored." The problem is that if
you want to write correct code, you must be able to prove it correct;
just saying it is correct, or finding a couple of data sets for which it
works isn't sufficient. Not having a defined order of evaluation
increases the number of possible combinations, which means that it is
significantly more difficult to write correct programs. As usual, we
find solutions, but they create extra work, and for what benefit.
--
James Kanze GABI Software mailto:kanze@gabi-soft.fr
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, T l. : +33 (0)1 30 23 45 16
---
[ 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 ]
Author: pierrebai@hotmail.com (Pierre Baillargeon)
Date: Tue, 1 Apr 2003 23:58:46 +0000 (UTC) Raw View
The problem caused by the unspecified order of evaluation of:
f(auto_ptr<X>(new X), auto_ptr<Y>(new Y))
could be avoided by changing the standard to say that while the order
is unspecifed, it must be a depth-first traversal of the syntax. That
is, the evaluation could be:
- new X
- auto_ptr<X> constructor
- new Y
- auto_ptr<Y> constructor
- f()
or the same with all X and Y exchanged. But the order could not be
that both new expressions are evaluated before both auto_ptr. Exact
wording could be tricky, but I think it would map to what programmer
instinctively expect while leaving LtoR or RtoL order at the
discretion of compilers.
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Wed, 2 Apr 2003 16:46:55 +0000 (UTC) Raw View
Pierre Baillargeon wrote:
> Exact wording could be tricky, but I think it would map to
> what programmer instinctively expect while leaving LtoR or
> RtoL order at the discretion of compilers.
Instead of opting for tricky wording, why don't we opt
for simple wording, so that we can tell programmers
what to expect, instead of relying on their instincts?
---
[ 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 ]
Author: nid_oizo@yahoo.com_removethe_ (Nicolas Fleury)
Date: Wed, 2 Apr 2003 18:32:10 +0000 (UTC) Raw View
Hyman Rosen wrote:
> Pierre Baillargeon wrote:
>
>> Exact wording could be tricky, but I think it would map to
>
> > what programmer instinctively expect while leaving LtoR or
> > RtoL order at the discretion of compilers.
>
> Instead of opting for tricky wording, why don't we opt
> for simple wording, so that we can tell programmers
> what to expect, instead of relying on their instincts?
Could this simple wording be "`,` separator introduces sequence points"?
Nicolas Fleury
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Wed, 2 Apr 2003 19:37:48 +0000 (UTC) Raw View
Nicolas Fleury wrote:
> Could this simple wording be "`,` separator introduces sequence points"?
No.
---
[ 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 ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Thu, 3 Apr 2003 01:29:17 +0000 (UTC) Raw View
hyrosen@mail.com (Hyman Rosen) wrote
> Nicolas Fleury wrote:
> > Could this simple wording be "`,` separator introduces sequence points"?
>
> No.
Couldn't it?
Mind you, I'm not in favor of the proposal -- but let's talk wording.
If the whole point is to completely evaluate one parameter before you
start evaluating the next one, then Nicolas's wording seems to do
exactly that. He doesn't mention the context (evaluating parameters),
but that's about the only place that isn't already a sequence point
at runtime anyway.
// These commas are already sequence points
int a = (foo(),bar(),baz());
// These commas don't have run-time performance at all.
int b[] = {10, 20, 30, 40};
So, why wouldn't Nicolas's wording do what he wants?
---
[ 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 ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Thu, 3 Apr 2003 04:51:44 +0000 (UTC) Raw View
pierrebai@hotmail.com (Pierre Baillargeon) wrote
> The problem caused by the unspecified order of evaluation of:
>
> f(auto_ptr<X>(new X), auto_ptr<Y>(new Y))
>
> could be avoided by changing the standard to say that while the order
> is unspecifed, it must be a depth-first traversal of the syntax. That
> is, the evaluation could be:
>
> - new X
> - auto_ptr<X> constructor
> - new Y
> - auto_ptr<Y> constructor
> - f()
>
> or the same with all X and Y exchanged. But the order could not be
> that both new expressions are evaluated before both auto_ptr. Exact
> wording could be tricky, but I think it would map to what programmer
> instinctively expect while leaving LtoR or RtoL order at the
> discretion of compilers.
Wouldn't that be a limiting factor on computers with multiple
processors? Imagine a hypothetical system that could use multiple
processors automatically, without forcing the programmer to manually
create multiple threads and synchronization mechanisms. If the
compiler knows how to generate code that evaluates
auto_ptr<X>(new X)
at the very same time that it also evaluates
auto_ptr<Y>(new Y)
and it also knows how to wait for both to finish before it calls f()...
well, your rule would prevent it from working like that.
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 3 Apr 2003 07:01:11 +0000 (UTC) Raw View
Allan W wrote:
> If the compiler knows how to generate code that evaluates
> auto_ptr<X>(new X)
> at the very same time that it also evaluates
> auto_ptr<Y>(new Y)
then it still isn't allowed to do it, because the Standard
forbids interleaving execution of function calls. Unless it
could do it as-if it was sequential. Which it can do anyway.
And worrying about pessimization of non-existent computers
to the detriment of existing programmers is less than useful.
---
[ 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 ]
Author: francis.glassborow@ntlworld.com (Francis Glassborow)
Date: Thu, 20 Mar 2003 18:15:19 +0000 (UTC) Raw View
In article <3E789BBC.391CC5C5@unet.univie.ac.at>, Thomas Mang
<a9804814@unet.univie.ac.at> writes
>What is an evaluation problem in
>
>x = ++x ?
>
>I mean, how shall the assignment take place before the expression right of '='
>is evaluated? How can this cause interlace / incorrect order?
>I am well aware that this is another story : foo(++x, ++x).
>And out of interested, are there implementations were code such x = ++x really
>does something else as if I wrote this?:
>
>++x;
>x = x;
>
>
>If yes, I wonder if the potentiality for aliasing isn't a good reason to make
>it not undefined.
You are confusing the process of evaluation with the process of storage.
++x must be evaluated before the assignment is evaluated but the only
requirement that C++ makes re storage (writing back to memory) is that
it must be complete before the following sequence point.
I do not know if there is hardware currently shipping where there would
be a problem, but there certainly has been in the past (compilers
inserted one or more wait states at sequence points to allow memory
writes to complete).
--
ACCU Spring Conference 2003 April 2-5
The Conference you cannot afford to miss
Check the details: http://www.accuconference.co.uk/
Francis Glassborow ACCU
---
[ 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 ]
Author: kanze@gabi-soft.de (James Kanze)
Date: Thu, 20 Mar 2003 18:15:46 +0000 (UTC) Raw View
ron@sensor.com ("Ron Natalie") wrote in message
news:<uG6ea.23796$VD2.7171@fe03.atl2.webusenet.com>...
> "Hyman Rosen" <hyrosen@mail.com> wrote in message
> news:1048094272.771703@master.nyc.kbcfp.com...
> > Nice and simple. No reason at all for C++ not to adopt the same
> > rules.
> If we wanted C++ to be as slow as Java, that would be fine. Some of
> us are trying to get work done though. Sticking seqeunce points after
> every operator is not the way to solve things.
That's just an old wives tale. Can you show a case where it would make
a measurable difference, or are you just repeating the same old fairy
tale that you've heard elsewhere?
I (and others before me) have asked for some concrete example. To date,
no one has been able to provide one.
(And by the way, I've got benchmarks where Java is *faster* than C++.
All you need is a lot of array accesses -- C/C++'s aliasing literally
shuts down the optimizer.)
--
James Kanze GABI Software mailto:kanze@gabi-soft.fr
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, T l. : +33 (0)1 30 23 45 16
---
[ 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 ]
Author: comp.std.c++_2003-03-20@nmhq.net (Niklas Matthies)
Date: Thu, 20 Mar 2003 20:26:49 +0000 (UTC) Raw View
On 2003-03-20 05:59, Gabriel Dos Reis <gdr@integrable-solutions.net> wrote:
> hyrosen@mail.com (Hyman Rosen) writes:
>| Andrew Koenig wrote:
>| > What other languages define "x = ++x"?
>|
>| Java and C#. The left side is evaluated, and the
>| lvalue is saved. The right side is evaluated,
>| incrementing x. That rvalue is then stored in the
>| saved lvalue (where it already is, in this case).
>|
>| Simple. Easy to explain. No sequence points needed.
>| No undefined behavior. How nice if C++ had it.
>
> What is the usefulness of such expression?
To not have to worry about avoiding such expressions.
Things can get non-obvious for example due to aliasing.
Seemingly innocuous expressions like
f(shared_ptr<X>(new X), G())
would (supposedly) turn safe as well.
The question should be: Are there expressions where performance would
be significantly hurt by mandating a particular order of evaluation?
-- Niklas Matthies
---
[ 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 ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: Thu, 20 Mar 2003 20:26:53 +0000 (UTC) Raw View
On Thu, 20 Mar 2003 02:20:41 +0000 (UTC), hyrosen@mail.com (Hyman Rosen)
wrote:
> Andrew Koenig wrote:
> > What other languages define "x = ++x"?
> Java and C#. The left side is evaluated, and the
> lvalue is saved. The right side is evaluated,
> incrementing x. That rvalue is then stored in the
> saved lvalue (where it already is, in this case).
In C++, ++x is an lvalue. How does ++x %= n behave
in those other languages? A very useful expression
for circular buffers.
John
---
[ 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 ]
Author: ron@sensor.com ("Ron Natalie")
Date: Thu, 20 Mar 2003 20:26:59 +0000 (UTC) Raw View
"Hyman Rosen" <hyrosen@mail.com> wrote in message news:1048114820.266329@master.nyc.kbcfp.com...
> Andrew Koenig wrote:
> > What other languages define "x = ++x"?
>
> Java and C#. The left side is evaluated, and the
> lvalue is saved. The right side is evaluated,
> incrementing x. That rvalue is then stored in the
> saved lvalue (where it already is, in this case).
>
> Simple. Easy to explain. No sequence points needed.
> No undefined behavior. How nice if C++ had it.
What do you mean no sequence points needed. It forces
the a sequence point after the ++ operation. That's the whole
definition of a sequence point. You don't know that x has received
the stored value without one.
What you are asking for is for all modifying operations ot have an
explicit sequence point after them.
---
[ 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 ]
Author: ron@sensor.com ("Ron Natalie")
Date: Thu, 20 Mar 2003 20:27:10 +0000 (UTC) Raw View
"Hyman Rosen" <hyrosen@mail.com> wrote in message news:ywaea.59246$68.55095@nwrdny01.gnilink.net...
> Ron Natalie wrote:
> > This implies that everytime someone does ++ or -- that you force the value to be stored back
> > to x. The language doesn't require this now, and to do so would be a performance issue.
>
> It requires as-if behavior, that's all. In any expression with ++ or --
> the value has to be stored back eventually, so the current rules don't
> avoid that. At most, the compiler gets to rearrange when the storeback
> happens.
For x = ++x, it is a trivial matter, but that would be a special
case. To say it must be so for ALL ++ operations, however would
mean that you'd have to force a sequence point, effectively any register
copies of x would be forced back into memory. This would BE a serious
performance problem!
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 20 Mar 2003 20:27:16 +0000 (UTC) Raw View
Gabriel Dos Reis wrote:
> What is the usefulness of such expression?
Making side-effects happen in a deterministic order
is useful, because you can then write programs to
rely on this behavior. Making code undefined is bad,
because it serves no one. I have not seen anyone
demonstrate the supposed efficiency benefits of
allowing side effects to be reordered.
---
[ 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 ]
Author: ron@sensor.com ("Ron Natalie")
Date: Thu, 20 Mar 2003 20:27:36 +0000 (UTC) Raw View
"Hyman Rosen" <hyrosen@mail.com> wrote in message news:1048098340.960204@master.nyc.kbcfp.com...
> Ron Natalie wrote:
> > Because it absolves the code generator for the side effect
> > from having to worry about consistancy with other modifications
> > that may occur to x.
>
> This is not a valid argument. If I were to write
> ++x; x = x;
You explicitly asked for a sequence point there.
> then the compiler would have to get the order correct.
> Compilers have to obey the language rules, and having a
> specified order of evaluation is not more complex than
> not having one.
It's not a complexity issue, it's a performance issue. By mandating
that the side effect must always occur before the expression can
be further evaluated you introduce an inefficency that is not warranted
in the general case just to make this particular degenerate case well
behaved.
---
[ 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 ]
Author: ron@sensor.com ("Ron Natalie")
Date: Thu, 20 Mar 2003 20:27:48 +0000 (UTC) Raw View
"James Kanze" <kanze@gabi-soft.de> wrote in message news:d6651fb6.0303200741.12ff756f@posting.google.com...
> That's just an old wives tale. Can you show a case where it would make
> a measurable difference, or are you just repeating the same old fairy
> tale that you've heard elsewhere?
It's not the order of operations, it's forcing the sequence point. Are you
trying to show me that having to write back to memory prematurely is
a feature that's not going to affect performance? Have you ever worked
with a good compiler (NOT GCC) on a machine where instruction scheduling
is an issue? My specific experience with this is on the i860, but I suspect
the same holds true for the SPARC and other RISC processors. The
compiler reorders the loads and stores because by doing so avoids stalls
in the various stages of the processor.
x = =++x is a trivial simplification. Lets try
*x = ++ *y + *z'
In order to make this consistant, you must force the value out to memory before
*z is read. Memory loads aren't cheap operations. The 860 compiler would
prefer to load *z as early as possible so that it will have arrived in the register
before it is needed. The code would look something like:
ld.l (r4), r6 // load *y
ld.l (r5), r7 // load *z
adds 1, r6, r6 // incr temporary copy of *y
st.l r6, (r4) // store back...could happen at any time before seq pt., but now is good.
adds r6, r7, r8 // add
st.l r7, (r8)
In order to do what you are asking for it would need to do:
ld.l (r4), r6 // load *y
adds 1, r6, r6 // stall, r6 not read yet.
st.l r6, (r4)
ld.l (r5), r7 // load *z
adds r5, r7, r8 // stall, r7 not here yet.
st.l r7, (r8)
>
> (And by the way, I've got benchmarks where Java is *faster* than C++.
> All you need is a lot of array accesses -- C/C++'s aliasing literally
> shuts down the optimizer.)
Just goes to show you can write bad code in any language. I'm busy here
writing code that has to get specific work done in a small number of milliseconds.
Java and C++ are different languages. There's little need to Javify C++ if
it means losing the performance aspects that make it attractive.
---
[ 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 ]
Author: ron@sensor.com ("Ron Natalie")
Date: Thu, 20 Mar 2003 21:23:40 +0000 (UTC) Raw View
"Hyman Rosen" <hyrosen@mail.com> wrote in message news:traea.59244$68.58935@nwrdny01.gnilink.net...
> Ron Natalie wrote:
> > If we wanted C++ to be as slow as Java, that would be fine.
>
> Oh, now, this is completely disingenuous. You know as well as I
> that speed differences between C++ and Java have nothing to do
> with order of evaluation.
>
It's not disingenuous at the least. While Java has other serious performance
issues, your proposal WILL slow C++ down.
---
[ 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 ]
Author: kanze@gabi-soft.de (James Kanze)
Date: Thu, 20 Mar 2003 21:24:25 +0000 (UTC) Raw View
gdr@integrable-solutions.net (Gabriel Dos Reis) wrote in message
news:<m3n0jqu2pc.fsf@uniton.integrable-solutions.net>...
> hyrosen@mail.com (Hyman Rosen) writes:
> | Andrew Koenig wrote:
> | > What other languages define "x = ++x"?
> | Java and C#. The left side is evaluated, and the lvalue is
> | saved. The right side is evaluated, incrementing x. That rvalue is
> | then stored in the saved lvalue (where it already is, in this case).
> | Simple. Easy to explain. No sequence points needed. No undefined
> | behavior. How nice if C++ had it.
> What is the usefulness of such expression?
Reproduceable test results.
Regardless of what the language allows, statements should do only one
thing. You don't modify two variables in one expression, even if the
two variables are in fact the same one. (And yes, I know that there are
exceptions; anything IO-like, for example. But they aren't really at
issue here.) But whether I like it or not, errors do happen. And it is
very frustrating when they only occur in the optimized version which I
deliver to the customer, and not the debug version I test with.
> Personnaly, I would hate to see C++ actively support such codings.
Well, it already supports so many bad practices:-).
In this case, I don't look at it as supporting any new practice. I look
on it exactly as Hyman presents it: elimination of undefined behavior,
so that you can have more confidence in your tests.
--
James Kanze GABI Software mailto:kanze@gabi-soft.fr
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, T l. : +33 (0)1 30 23 45 16
---
[ 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 ]
Author: francis.glassborow@ntlworld.com (Francis Glassborow)
Date: Thu, 20 Mar 2003 21:25:06 +0000 (UTC) Raw View
In article <traea.59244$68.58935@nwrdny01.gnilink.net>, Hyman Rosen
<hyrosen@mail.com> writes
>Ron Natalie wrote:
>> If we wanted C++ to be as slow as Java, that would be fine.
>
>Oh, now, this is completely disingenuous. You know as well as I
>that speed differences between C++ and Java have nothing to do
>with order of evaluation.
You sure about that? The intention is that C++ is usable on a very wide
range of hardware some of which could not support a JVM. Java is
designed to run only on a Java machine or a JVM running on hardware that
can support it.
Consider:
a=3;
b=a;
c=b+a;
A strict interpretation of the Java rules requires that both b and a be
fetched after the address of (lvalue) c has been evaluated. In C++ this
isn't even a theoretical problem because the compiler just codes use of
what is already in registers.
--
ACCU Spring Conference 2003 April 2-5
The Conference you cannot afford to miss
Check the details: http://www.accuconference.co.uk/
Francis Glassborow ACCU
---
[ 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 ]
Author: gdr@integrable-solutions.net (Gabriel Dos Reis)
Date: Thu, 20 Mar 2003 21:25:53 +0000 (UTC) Raw View
comp.std.c++_2003-03-20@nmhq.net (Niklas Matthies) writes:
| On 2003-03-20 05:59, Gabriel Dos Reis <gdr@integrable-solutions.net> wrote:
| > hyrosen@mail.com (Hyman Rosen) writes:
| >| Andrew Koenig wrote:
| >| > What other languages define "x = ++x"?
| >|
| >| Java and C#. The left side is evaluated, and the
| >| lvalue is saved. The right side is evaluated,
| >| incrementing x. That rvalue is then stored in the
| >| saved lvalue (where it already is, in this case).
| >|
| >| Simple. Easy to explain. No sequence points needed.
| >| No undefined behavior. How nice if C++ had it.
| >
| > What is the usefulness of such expression?
|
| To not have to worry about avoiding such expressions.
Well, if the purpose is not to have to worry about such expressions,
then it occurs to me that the least thing to do is leave their semantics
undefined.
--
Gabriel Dos Reis, gdr@integrable-solutions.net
---
[ 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 ]
Author: gdr@integrable-solutions.net (Gabriel Dos Reis)
Date: Thu, 20 Mar 2003 21:56:41 +0000 (UTC) Raw View
hyrosen@mail.com (Hyman Rosen) writes:
| Gabriel Dos Reis wrote:
| > What is the usefulness of such expression?
|
| Making side-effects happen in a deterministic order
| is useful,
However making that expression well-defined does -not- make
side-effects happen in deterministic order.
| because you can then write programs to
| rely on this behavior. Making code undefined is bad,
| because it serves no one.
s/Make code undefined/Writing code with undefined behaviour/
and I might probably agree.
--
Gabriel Dos Reis, gdr@integrable-solutions.net
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 20 Mar 2003 21:56:46 +0000 (UTC) Raw View
Ron Natalie wrote:
> just to make this particular degenerate case well behaved.
The "non-degenerate" cases can pretty much work as before,
since those don't involve using and changing the same lvalue
in a single expression. C++ compilers can rearrange code as
much as they like if they don't violate observable semantics.
As I keep saying. I don't believe that requiring side-effects
to happen deterministically would have anything but the tiniest
impact on performance.
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 20 Mar 2003 21:56:50 +0000 (UTC) Raw View
Ron Natalie wrote:
> *x = ++ *y + *z'
> you must force the value out to memory before *z is read.
Declare x, y, and z with the 'restrict' modifier.
This is safe, becuase if it were not, the existing
code would have undefined behavior. Once you do,
then the expression can be compiled just as before.
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 20 Mar 2003 21:56:58 +0000 (UTC) Raw View
John Potter wrote:
> In C++, ++x is an lvalue. How does ++x %= n behave
> in those other languages? A very useful expression
> for circular buffers.
It's not an lvalue in Java. But the rule is left before
right, operands before operation. So in your example, we
evaluate ++x, applying the increment. Then we do the %=.
The result is as if you had said 'x = (x + 1) % n', except
that you just have to name 'x' once.
---
[ 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 ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Thu, 20 Mar 2003 21:57:41 +0000 (UTC) Raw View
hyrosen@mail.com (Hyman Rosen) wrote
> Java's rules are basically as follows:
...
> Nice and simple. No reason at all for C++ not
> to adopt the same rules.
If these really are Java's rules, they provide a great example of
why C++'s non-specifications are better. Look what happens when we
convert the code into some fictitious assembly language. I'll use
a "one-operand" language -- which means that we can use ONE address
or ONE immediate value per instruction (PDP-11s work this way, as
do most of the Intel instructions).
> 1) The left operand of a binary operation
> is fully evaluated before the right one.
> For compound assignment, the left value
> and its address is remembered before the
> right operand is evaluated.
> a = 1; a += (a = 3); // Now a == 4
Ignoring optimization (else we could simply optimize the
code to
a=4;
or
a=6;
proving nothing)
The C++ way
; a=1
000 Load Reg1, #1 ; Get the value 1
001 Store Reg1, A ; Save it in A
; a += (a=3)
002 Load Reg1, #3 ; Get the value 3
003 Store Reg1, A ; Save it in A, evaluating (a=3)
004 Add Reg1, A ; Add it to A, evaluating (a += value)
;;; Result: A=6
The Java way
; a=1
000 Load Reg1, #1 ; Get the value 1
001 Store Reg1, A ; Save it in A
; a += (a=3)
002 Load Reg1, A ; Get "old" value of A
003 Push Reg1 ; Save it on the stack
004 Load Reg1, #3 ; Get the value 3
005 Store Reg1, A ; Save it in A, evaluating (a=3)
006 Pop Reg1 ; Restore "old" value of A
007 Add Reg1, A ; Add it to A, evaluating (a += value)
;;; Result: A=4
The Java version is 75% bigger, and presumably 75% slower.
> 2) Operands of an operation are fully
> evaluated before the operation is
> done.
This rule is already the same as in C++. (How could it be otherwise?
You can't call foo with two values, until you compute those 2 values.)
> 3) Function call arguments are evaluated
> left-to-right.
On many platforms (i.e. Microsoft, Unix) the calling convention
requires pushing the rightmost argument on the stack first. This
facilitates varadic functions; the first argument (being pushed
last) is always in the same place on the stack.
By forcing us to evaluate arguments left-to-right, you force us to
either:
1. Save these values in a temporary place, and then rearrange
them when they've all been evaluated, or
2. Create space on the stack, and then populate them left-to-right
(which prevents us from using simple "push" instructions).
Either way, the code is bigger and slower. Naturally, this does not
apply when the calling convention is left-to-right...
---
[ 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 ]
Author: go_go_sonic@hotmail.com ("chris jefferson")
Date: Thu, 20 Mar 2003 21:57:46 +0000 (UTC) Raw View
""Ron Natalie"" <ron@sensor.com> wrote in message
news:NVnea.32853$334.7290@fe05.atl2.webusenet.com...
>
> "Hyman Rosen" <hyrosen@mail.com> wrote in message
news:1048098340.960204@master.nyc.kbcfp.com...
> > Ron Natalie wrote:
> > > Because it absolves the code generator for the side effect
> > > from having to worry about consistancy with other modifications
> > > that may occur to x.
> >
> > This is not a valid argument. If I were to write
> > ++x; x = x;
>
> You explicitly asked for a sequence point there.
>
> > then the compiler would have to get the order correct.
> > Compilers have to obey the language rules, and having a
> > specified order of evaluation is not more complex than
> > not having one.
>
> It's not a complexity issue, it's a performance issue. By mandating
> that the side effect must always occur before the expression can
> be further evaluated you introduce an inefficency that is not warranted
> in the general case just to make this particular degenerate case well
> behaved.
Any intellegant optimising compiler would be able to tell if it needed to
add extra control points to deal with this problem if it was inserted into
the standard. I'm certain it wouldn't slow things down in cases where the
special case didn't come up. On the other hand I agree that there is never
any purpose to doing this kind of thing :)
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 20 Mar 2003 21:57:55 +0000 (UTC) Raw View
Gabriel Dos Reis wrote:
> Well, if the purpose is not to have to worry about such expressions,
> then it occurs to me that the least thing to do is leave their semantics
> undefined.
To "not worry" means that it will do what you expect,
or at least not cause nasal demons. Undefined behavior
is a specific problem for C++ because if it is ever
encountered, you can no longer say anything about the
behavior of the program.
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 20 Mar 2003 21:59:22 +0000 (UTC) Raw View
Francis Glassborow wrote:
> Consider:
> a=3;
> b=a;
> c=b+a;
>
> A strict interpretation of the Java rules requires that both b and a be
> fetched after the address of (lvalue) c has been evaluated. In C++ this
> isn't even a theoretical problem because the compiler just codes use of
> what is already in registers.
I have a copy of _The Java(tm) Language Specification_ in front of me.
In describing order of evaluation, the word "appears" is used constantly,
to emphasize the as-if permissions granted to the system.
I don't see how the above code is any different in Java than in C++.
Why do you think that the Java requirements would prevent a, b, and c
from being held in registers?
---
[ 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 ]
Author: ron@sensor.com ("Ron Natalie")
Date: Thu, 20 Mar 2003 22:16:10 +0000 (UTC) Raw View
"Hyman Rosen" <hyrosen@mail.com> wrote in message news:1048193281.527388@master.nyc.kbcfp.com...
> Ron Natalie wrote:
> > just to make this particular degenerate case well behaved.
>
> The "non-degenerate" cases can pretty much work as before,
> since those don't involve using and changing the same lvalue
> in a single expression.
You don't know if they are the same lvalue or not. You are asking
for a goofy special case.
> As I keep saying. I don't believe that requiring side-effects
> to happen deterministically would have anything but the tiniest
> impact on performance.
You can keep saying that, but it doesn't make it true? Do you in fact
have any experience with machine instruction level processor performance?
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 20 Mar 2003 22:57:18 +0000 (UTC) Raw View
Allan W wrote:
> The C++ way
In C++, the expression a += (a = 3) has undefined behavior.
That you think it doesn't should tell you something about
why the other way is better.
> Ignoring optimization
Will give you large, slow code. So what?
>> 2) Operands of an operation are fully evaluated before
>> the operation is done.
>
> This rule is already the same as in C++. (How could it be otherwise?
> You can't call foo with two values, until you compute those 2 values.)
You're forgetting about side-effects.
That's what this rule is getting at.
// copy array[1..end] into array[0..end-1]
i = 0; while (i < a.size() - 1) a[i++] = a[i];
>> 3) Function call arguments are evaluated left-to-right.
>
> By forcing us to evaluate arguments left-to-right the code is
> bigger and slower.
Again, this would matter only when more than one argument had
side effects. And then, predictable behavior would be nice:
printf("%d a %d b %d c", inc_id(), inc_id(), inc_id());
cout << inc_id() << " a" << inc_id() << " b" << inc_id() << " c";
How many people have been caught out on that last one?
---
[ 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 ]
Author: francis.glassborow@ntlworld.com (Francis Glassborow)
Date: Thu, 20 Mar 2003 23:04:10 +0000 (UTC) Raw View
In article <1048193945.695310@master.nyc.kbcfp.com>, Hyman Rosen
<hyrosen@mail.com> writes
>Ron Natalie wrote:
>> *x = ++ *y + *z'
>> you must force the value out to memory before *z is read.
>
>Declare x, y, and z with the 'restrict' modifier.
>This is safe, becuase if it were not, the existing
>code would have undefined behavior. Once you do,
>then the expression can be compiled just as before.
All that the restrict qualifier does is to place the burden for not
aliasing onto the programmer, it does not place any requirement on the
compiler, on the contrary, its purpose is to allow the compiler to make
assumptions that it could not otherwise make.
--
ACCU Spring Conference 2003 April 2-5
The Conference you cannot afford to miss
Check the details: http://www.accuconference.co.uk/
Francis Glassborow ACCU
---
[ 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 ]
Author: ron@sensor.com ("Ron Natalie")
Date: Thu, 20 Mar 2003 23:04:37 +0000 (UTC) Raw View
"Hyman Rosen" <hyrosen@mail.com> wrote in message news:1048200955.641300@master.nyc.kbcfp.com...
> Allan W wrote:
> > The C++ way
>
> In C++, the expression a += (a = 3) has undefined behavior.
> That you think it doesn't should tell you something about
> why the other way is better.
>
Well you can argue this all you want, but it ain't going to happen:
1. It's not compatible with C.
2. It's slower.
3. There are more pressing issues with C++.
If we were going to make a lockstep rigid evaluation order and side-effect application,
then we could fix other C++ historical stupidiies:
1. The fact that default initializaiton isn't consistantly performed.
2. Arrays not behaving properly w.r.t. assignment, copying.
3. Defects in the library international language support.
All the above bite me more seriously than expression ordering issues.
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 20 Mar 2003 23:46:19 +0000 (UTC) Raw View
Francis Glassborow wrote:
> All that the restrict qualifier does is to place the burden for not
> aliasing onto the programmer, it does not place any requirement on the
> compiler, on the contrary, its purpose is to allow the compiler to make
> assumptions that it could not otherwise make.
The piece of code in question was
*x = ++*y + *z;
The burden was already on the programmer, because if restrict
does in fact not apply to y, then the behavior is undefined.
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Fri, 21 Mar 2003 05:04:32 +0000 (UTC) Raw View
Ron Natalie wrote:
> 1. It's not compatible with C.
It most certainly is. Defining previously undefined or unspecified
behavior cannot make code less compatible.
> 2. It's slower.
Quite arguable for the majority of cases, and a worthwhile
tradeoff for the expressive benefit and lack of astonishment.
> 3. There are more pressing issues with C++.
Those aren't going to get done either.
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Wed, 19 Mar 2003 17:40:45 +0000 (UTC) Raw View
Ron Natalie wrote:
> Really? Which langauge? How do they resolve the ambiguity?
Java. Evaluation order is left before right, operands before
operation, and function arguments from left to right. What
ambiguity?
> 1. That there essentially be the equivelent of a sequence
> point around every subexpression with a side effect.
Yes. Actually, the whole concept of sequence points vanishes
into the dustbin of history, where it belongs. The compiler
gets to as-if its way into efficiency where it can, and the
programmer gets deterministic and defined behavior. How nice.
---
[ 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 ]
Author: ark@research.att.com (Andrew Koenig)
Date: Wed, 19 Mar 2003 22:18:11 +0000 (UTC) Raw View
Thomas> What advantage can compiler writers take off by resulting "x = ++x" in
Thomas> undefined behavior?
Thomas> Other languages clearly define this construct, C++ not. Is there any
Thomas> hard-fact reason to make this undefined?
The main reason that "x = ++x" is undefined in C++ is that it is
undefined in C, and C++ tried not to mess with how C defines
arithmetic.
What other languages define "x = ++x"?
--
Andrew Koenig, ark@research.att.com, http://www.research.att.com/info/ark
---
[ 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 ]
Author: a9804814@unet.univie.ac.at (Thomas Mang)
Date: Wed, 19 Mar 2003 22:18:42 +0000 (UTC) Raw View
Francis Glassborow schrieb:
> In article <3E77A765.511F8699@unet.univie.ac.at>, Thomas Mang
> <a9804814@unet.univie.ac.at> writes
> >Here I ask too:
> >
> >What advantage can compiler writers take off by resulting "x = ++x" in
> >undefined behavior?
> >Other languages clearly define this construct, C++ not. Is there any
> >hard-fact reason to make this undefined?
> >
> >If I am not mistaken, this is also undefined, but is much more likely to
> >happen in pracice than the expression above:
> >
> >int a = 0;
> >int & b = a;
> >a = ++b;
> >
> >
> >Here, aliasing hides the fact that actually a is modified 2 times without
> >sequence point between write - accesses.(Or am I totally wrong and the
> >reference adds a sequence point??).
> >
> >It was/is quite popular to check in the assignment-operator against
> >self-assignment before freeing ressources. However, I have never seen
> >checking for aliasing in code such as the one above. Pitfall, isn't it ?
>
> Checking for aliasing would introduce a serious overhead for all
> programs and that is contrary to the general philosophies of C and C++
This is well true, but OTOH undefined behavior is also not the philosophy of
C++ programs - no matter how fast I get the undefined behavior.
>
>
> The problem with two writes to the same memory between sequence points
> is that it would rely on the OS scheduling such writes so that:
> a) they do not interlace
> b) they occur in the correct order.
I know my knowledge about hardware, OS and CPUs is definitly not at a level to
go into really hard-technical details, but I still wonder:
What is an evaluation problem in
x = ++x ?
I mean, how shall the assignment take place before the expression right of '='
is evaluated? How can this cause interlace / incorrect order?
I am well aware that this is another story : foo(++x, ++x).
And out of interested, are there implementations were code such x = ++x really
does something else as if I wrote this?:
++x;
x = x;
If yes, I wonder if the potentiality for aliasing isn't a good reason to make
it not undefined.
best regards,
Thomas
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Wed, 19 Mar 2003 22:18:49 +0000 (UTC) Raw View
Thomas Mang wrote:
> What advantage can compiler writers take off
> by resulting "x = ++x" in undefined behavior?
None at all. It's just always been done that way
in C, and C++ picked it up. Java corrected the
problem by specifying evaluation order in detail.
Gratuitous undefined behavior should be removed
from the language where possible, and the whole
order of evaluation / sequence point thing is
ideal for cleaning up.
Java's rules are basically as follows:
1) The left operand of a binary operation
is fully evaluated before the right one.
For compound assignment, the left value
and its address is remembered before the
right operand is evaluated.
a = 1; a += (a = 3); // Now a == 4
i = 1; a[i] = (i = 2) ; // Now a[1] == 2
2) Operands of an operation are fully
evaluated before the operation is
done.
3) Function call arguments are evaluated
left-to-right.
Nice and simple. No reason at all for C++ not
to adopt the same rules.
---
[ 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 ]
Author: a9804814@unet.univie.ac.at (Thomas Mang)
Date: Wed, 19 Mar 2003 22:18:57 +0000 (UTC) Raw View
Ron Natalie schrieb:
> "Thomas Mang" <a9804814@unet.univie.ac.at> wrote in message news:3E77A765.511F8699@unet.univie.ac.at...
>
> > What advantage can compiler writers take off by resulting "x = ++x" in
> > undefined behavior?
>
> Because it absolves the code generator for the side effect from having to worry
> about consistancy with other modifications that may occur to x.
>
> > Other languages clearly define this construct, C++ not. Is there any
> > hard-fact reason to make this undefined?
>
> Really? Which langauge? How do they resolve the ambiguity?
Java does.
As I don't know to which ambiguity you refer, I can't answer that.
>
> The decision was that the code generator could be more efficient
> if it was allowed to not be constrained to apply the side effect at
> any given time. Sure the compiler could detect x = ++x at compile
> time, but what about:
>
> >
> > Here, aliasing hides the fact that actually a is modified 2 times without
> > sequence point between write - accesses.(Or am I totally wrong and the
> > reference adds a sequence point??).
>
> This is precisely why the compiler is absolved from having to worry about it.
> To do otherwise would require either:
>
> 1. That there essentially be the equivelent of a sequence point around every
> subexpression with a side effect.
> 2. That the runtime code would need to check to see if the same value
> is being modified within the expression.
>
> >
> > It was/is quite popular to check in the assignment-operator against
> > self-assignment before freeing ressources. However, I have never seen
> > checking for aliasing in code such as the one above. Pitfall, isn't it ?
> >
> Only for poor programmers. What possible use is the dubious expression
> you have written?
Why dubious?
You get somewhere a reference to a built-in type, modify it there and store the pre-/post-incremented
value.
Take (plain-pointer) iterators for example. Increment one, store the previous/new position in another one.
And hope they hadn't been the same.
regards,
Thomas
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 20 Mar 2003 02:20:41 +0000 (UTC) Raw View
Andrew Koenig wrote:
> What other languages define "x = ++x"?
Java and C#. The left side is evaluated, and the
lvalue is saved. The right side is evaluated,
incrementing x. That rvalue is then stored in the
saved lvalue (where it already is, in this case).
Simple. Easy to explain. No sequence points needed.
No undefined behavior. How nice if C++ had it.
---
[ 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 ]
Author: ron@sensor.com ("Ron Natalie")
Date: Thu, 20 Mar 2003 02:20:48 +0000 (UTC) Raw View
"Thomas Mang" <a9804814@unet.univie.ac.at> wrote in message news:3E789BBC.391CC5C5@unet.univie.ac.at...
>
> What is an evaluation problem in
>
> x = ++x ?
Because you don't know when the side effect is applied. In this simple expression, you
are right, it's probably going to emit safe code anyhow, but with a more complex expression:
x = ++x + x
or such it's going to be dangerous.
> ++x;
> x = x;
This implies that everytime someone does ++ or -- that you force the value to be stored back
to x. The language doesn't require this now, and to do so would be a performance issue.
The issue is to not special case this very specific simple case because the general case is
so much harder.
---
[ 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 ]
Author: ron@sensor.com ("Ron Natalie")
Date: Thu, 20 Mar 2003 02:20:54 +0000 (UTC) Raw View
"Hyman Rosen" <hyrosen@mail.com> wrote in message news:1048094272.771703@master.nyc.kbcfp.com...
> Nice and simple. No reason at all for C++ not
> to adopt the same rules.
>
If we wanted C++ to be as slow as Java, that would be fine.
Some of us are trying to get work done though. Sticking seqeunce
points after every operator is not the way to solve things.
---
[ 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 ]
Author: gdr@integrable-solutions.net (Gabriel Dos Reis)
Date: Thu, 20 Mar 2003 05:59:21 +0000 (UTC) Raw View
hyrosen@mail.com (Hyman Rosen) writes:
| Andrew Koenig wrote:
| > What other languages define "x = ++x"?
|
| Java and C#. The left side is evaluated, and the
| lvalue is saved. The right side is evaluated,
| incrementing x. That rvalue is then stored in the
| saved lvalue (where it already is, in this case).
|
| Simple. Easy to explain. No sequence points needed.
| No undefined behavior. How nice if C++ had it.
What is the usefulness of such expression?
Personnaly, I would hate to see C++ actively support such codings.
--
Gabriel Dos Reis, gdr@integrable-solutions.net
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 20 Mar 2003 05:59:26 +0000 (UTC) Raw View
Ron Natalie wrote:
> This implies that everytime someone does ++ or -- that you force the value to be stored back
> to x. The language doesn't require this now, and to do so would be a performance issue.
It requires as-if behavior, that's all. In any expression with ++ or --
the value has to be stored back eventually, so the current rules don't
avoid that. At most, the compiler gets to rearrange when the storeback
happens. It would take extraordinary proof for me to believe that this
freedom provides enough of an advantage for the decades of undefined
behavior we've had to endure.
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 20 Mar 2003 05:59:40 +0000 (UTC) Raw View
Ron Natalie wrote:
> If we wanted C++ to be as slow as Java, that would be fine.
Oh, now, this is completely disingenuous. You know as well as I
that speed differences between C++ and Java have nothing to do
with order of evaluation.
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 20 Mar 2003 18:12:21 +0000 (UTC) Raw View
Ron Natalie wrote:
> Because it absolves the code generator for the side effect
> from having to worry about consistancy with other modifications
> that may occur to x.
This is not a valid argument. If I were to write
++x; x = x;
then the compiler would have to get the order correct.
Compilers have to obey the language rules, and having a
specified order of evaluation is not more complex than
not having one.
---
[ 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 ]
Author: nid_oizo@yahoo.com_removethe_ (Nicolas Fleury)
Date: Thu, 20 Mar 2003 18:12:40 +0000 (UTC) Raw View
Thomas Mang wrote:
> Here I ask too:
>
> What advantage can compiler writers take off by resulting "x = ++x" in
> undefined behavior?
> Other languages clearly define this construct, C++ not. Is there any
> hard-fact reason to make this undefined?
For my part, I wonder if C++ should define more execution order than
currently. For example:
string foo() { cout << "y"; return "z"; }
cout << "x" << foo();
can print "xyz" or "yxz"
or
foo(auto_ptr<X>(new X), auto_ptr<Y>(new Y));
is problematic if constructors throw exceptions, but it could not if
execution order was to complete construction of first auto_ptr before
instanciating the Y object.
Would it make sense to be more restrictive on execution order?
Regards,
Nicolas Fleury
---
[ 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 ]
Author: naolerei@yahoo.com (Leo)
Date: Tue, 18 Mar 2003 17:41:50 +0000 (UTC) Raw View
Does anyone know why evaluating expressions from right to left is a
sensible design choice in C++? Just to clarify: I'm not questioning if
it does that. I know it does. The question is why do that? Here is a
small example:
//----------------------------------------------------
#include <iostream>
using namespace std;
class A{
public:
A(string s){ cout << s << endl;}
};
void f(const A& a, const A& b){}
int main(void){
A("LV") = A("RV");
f(A("1st"),A("2nd"));
// f(a = A("1"),a);
return 0;
}
//----------------------------------------------------
The output from this program is:
--------------
RV
LV
2nd
1st
--------------
and uncommenting the line before the return statement causes a
compilation error. Can someone explain why this should be so?
Thx.
Leo.
---
[ 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 ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Tue, 18 Mar 2003 19:52:47 +0000 (UTC) Raw View
Leo wrote:
> Does anyone know why evaluating expressions from right to left is a
> sensible design choice in C++? Just to clarify: I'm not questioning if
> it does that. I know it does.
You "know" incorrectly. In fact, order of evaluation is
unspecified, and the compiler is free to choose any order
it likes. In some cases, like your commented out statement,
you can cause undefined behavior if you modify an lvalue
twice without an intervening sequence point.
> The question is why do that?
The traditional implementation of variadic functions
(such as printf) takes a pointer to its first argument
and steps through the parameters by incrementing the
pointer. In order for this to work, the parameters
have to be pushed on the stack in reverse order, from
right to left. Using this method also lets you treat
variadic and non-variadic functions identically, so it
became a somewhat standard way to do things.
---
[ 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 ]
Author: stephen.clamage@sun.com (Stephen Clamage)
Date: Tue, 18 Mar 2003 19:54:13 +0000 (UTC) Raw View
Your premise is false. Expressions are not necessarily evaluated right
to left. The expression grammar defines precedence and associativity
that sometimes force an evaluation order -- but not necessarily right
to left. Where the order is not forced, the compiler can choose any
order.
Beyond that, some operations have undefined behavior, where not only
the order, but the result of the computation might be anything.
In the statement
A("LV") = A("RV");
the expression A("RV") must be completed before it can be assigned to
the (temporary) object on the left side. The construction of the left
side can occur before or after the one on the right. Your compiler,
using whatever set of compilation options you provided, chose to
completely construct the right side before the left side. That choice
is arbitrary, not required.
In the call to f, both arguments must be evaluated before f can be
called. The order of evaluation is "unspecified", meaning the compiler
can choose any order, and need not always choose the same order.
Different compilers, and possibly the same compiler with different
compilation options, might choose different evaluation orders.
The commented-out line is not valid because the variable 'a' has no
declaration in function main.
Finally, your program uses the std::string type without ever including
the <string> header. The code won't compile at all on some systems.
Only by accident (the iostream header including string) does it
compile using your compiler.
On Tue, 18 Mar 2003 17:41:50 +0000 (UTC), naolerei@yahoo.com (Leo)
wrote:
>Does anyone know why evaluating expressions from right to left is a
>sensible design choice in C++? Just to clarify: I'm not questioning if
>it does that. I know it does. The question is why do that? Here is a
>small example:
>
>//----------------------------------------------------
>#include <iostream>
>
>using namespace std;
>
>class A{
> public:
> A(string s){ cout << s << endl;}
>};
>void f(const A& a, const A& b){}
>int main(void){
> A("LV") = A("RV");
> f(A("1st"),A("2nd"));
>// f(a = A("1"),a);
> return 0;
>}
>//----------------------------------------------------
>
>The output from this program is:
>--------------
>RV
>LV
>2nd
>1st
>--------------
>
>and uncommenting the line before the return statement causes a
>compilation error. Can someone explain why this should be so?
>
>Thx.
>Leo.
>
>---
>[ 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 ]
---
Steve Clamage, stephen.clamage@sun.com
---
[ 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 ]
Author: ron@sensor.com ("Ron Natalie")
Date: Tue, 18 Mar 2003 22:51:13 +0000 (UTC) Raw View
"Leo" <naolerei@yahoo.com> wrote in message news:efc4aa34.0303180733.7cbd8738@posting.google.com...
> Does anyone know why evaluating expressions from right to left is a
> sensible design choice in C++? Just to clarify: I'm not questioning if
> it does that. I know it does. The question is why do that? Here is a
> small example:
You are wrong. The order of evaluation is not specified (except in certain
cases). You are just observing the behavior of your specific compiler in
one particular circumstance.
Many compilers that use stack based arg passing will evaluate the right
most function arg first. However, that's no guarantee. RISC processers
tend to pass things in registers and hence the evaluation of the function
parameters is less deterministic.
>
> and uncommenting the line before the return statement causes a
> compilation error. Can someone explain why this should be so?
Because you declared a as const A&. The default operator= is not
a const method.
---
[ 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 ]
Author: a9804814@unet.univie.ac.at (Thomas Mang)
Date: Wed, 19 Mar 2003 08:14:39 +0000 (UTC) Raw View
Hyman Rosen schrieb:
> Leo wrote:
> > Does anyone know why evaluating expressions from right to left is a
> > sensible design choice in C++? Just to clarify: I'm not questioning if
> > it does that. I know it does.
>
> You "know" incorrectly. In fact, order of evaluation is
> unspecified, and the compiler is free to choose any order
> it likes. In some cases, like your commented out statement,
> you can cause undefined behavior if you modify an lvalue
> twice without an intervening sequence point.
Here I ask too:
What advantage can compiler writers take off by resulting "x = ++x" in
undefined behavior?
Other languages clearly define this construct, C++ not. Is there any
hard-fact reason to make this undefined?
If I am not mistaken, this is also undefined, but is much more likely to
happen in pracice than the expression above:
int a = 0;
int & b = a;
a = ++b;
Here, aliasing hides the fact that actually a is modified 2 times without
sequence point between write - accesses.(Or am I totally wrong and the
reference adds a sequence point??).
It was/is quite popular to check in the assignment-operator against
self-assignment before freeing ressources. However, I have never seen
checking for aliasing in code such as the one above. Pitfall, isn't it ?
best regards,
Thomas
---
[ 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 ]
Author: francis.glassborow@ntlworld.com (Francis Glassborow)
Date: Wed, 19 Mar 2003 08:14:47 +0000 (UTC) Raw View
In article <efc4aa34.0303180733.7cbd8738@posting.google.com>, Leo
<naolerei@yahoo.com> writes
>Does anyone know why evaluating expressions from right to left is a
>sensible design choice in C++? Just to clarify: I'm not questioning if
>it does that. I know it does. The question is why do that? Here is a
>small example:
Then you know something that is not true. And you cannot deduce C++
requirements from the output of a program. The only requirements placed
on evaluation of expressions is that the operands of an operator and the
arguments of a function must be evaluated in time to be used and that
operators must themselves be evaluated according to the rules for
precedence and 'associativety'
--
ACCU Spring Conference 2003 April 2-5
The Conference you cannot afford to miss
Check the details: http://www.accuconference.co.uk/
Francis Glassborow ACCU
---
[ 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 ]
Author: francis.glassborow@ntlworld.com (Francis Glassborow)
Date: Wed, 19 Mar 2003 15:47:08 +0000 (UTC) Raw View
In article <3E77A765.511F8699@unet.univie.ac.at>, Thomas Mang
<a9804814@unet.univie.ac.at> writes
>Here I ask too:
>
>What advantage can compiler writers take off by resulting "x = ++x" in
>undefined behavior?
>Other languages clearly define this construct, C++ not. Is there any
>hard-fact reason to make this undefined?
>
>If I am not mistaken, this is also undefined, but is much more likely to
>happen in pracice than the expression above:
>
>int a = 0;
>int & b = a;
>a = ++b;
>
>
>Here, aliasing hides the fact that actually a is modified 2 times without
>sequence point between write - accesses.(Or am I totally wrong and the
>reference adds a sequence point??).
>
>It was/is quite popular to check in the assignment-operator against
>self-assignment before freeing ressources. However, I have never seen
>checking for aliasing in code such as the one above. Pitfall, isn't it ?
Checking for aliasing would introduce a serious overhead for all
programs and that is contrary to the general philosophies of C and C++
The problem with two writes to the same memory between sequence points
is that it would rely on the OS scheduling such writes so that:
a) they do not interlace
b) they occur in the correct order.
There are two major reasons for making an action have undefined
behaviour:
1) Detecting it at compilation time is either impossible (because it is
dependant on runtime input, or cross TU) or very difficult, requiring a
level of code analysis that is deemed unacceptable for current
technology.
2) To allow Platform specific behaviour that cannot reasonably be
required for all potential platforms.
--
ACCU Spring Conference 2003 April 2-5
The Conference you cannot afford to miss
Check the details: http://www.accuconference.co.uk/
Francis Glassborow ACCU
---
[ 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 ]
Author: ron@sensor.com ("Ron Natalie")
Date: Wed, 19 Mar 2003 17:12:03 +0000 (UTC) Raw View
"Thomas Mang" <a9804814@unet.univie.ac.at> wrote in message news:3E77A765.511F8699@unet.univie.ac.at...
> What advantage can compiler writers take off by resulting "x = ++x" in
> undefined behavior?
Because it absolves the code generator for the side effect from having to worry
about consistancy with other modifications that may occur to x.
> Other languages clearly define this construct, C++ not. Is there any
> hard-fact reason to make this undefined?
Really? Which langauge? How do they resolve the ambiguity?
The decision was that the code generator could be more efficient
if it was allowed to not be constrained to apply the side effect at
any given time. Sure the compiler could detect x = ++x at compile
time, but what about:
>
> Here, aliasing hides the fact that actually a is modified 2 times without
> sequence point between write - accesses.(Or am I totally wrong and the
> reference adds a sequence point??).
This is precisely why the compiler is absolved from having to worry about it.
To do otherwise would require either:
1. That there essentially be the equivelent of a sequence point around every
subexpression with a side effect.
2. That the runtime code would need to check to see if the same value
is being modified within the expression.
>
> It was/is quite popular to check in the assignment-operator against
> self-assignment before freeing ressources. However, I have never seen
> checking for aliasing in code such as the one above. Pitfall, isn't it ?
>
Only for poor programmers. What possible use is the dubious expression
you have written?
---
[ 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 ]