Topic: I need a language lawyer...


Author: pkt@lpi.liant.com (Scott Turner)
Date: Wed, 3 Nov 1993 15:31:39 GMT
Raw View
In article <tjmCFvxzx.4FE@netcom.com>, tjm@netcom.com (Thomas J. Merritt) writes:

> One question remains though.  Can the copying
> of t to the return value of operator- be eliminated by by merging t with
> the return value.  In other words, assume that we have.

> HugeInt operator-(HugeInt const &l, HugeInt const &r)
> {
>     HugeInt t = l;  // 1
>     t -= r;   // 2
>     return t;   // 3
> }

> 3) must map to
>  if (&returnvalue != &t)
>      (&returnvalue)->HugeInt::HugeInt(t);
>
> The question is then, can (&returnvalue == &t) ever be TRUE?

Since your organization is "Code Generation Technology" I'll answer
as if you are deciding which way to go in implementing a compiler.
Regardless of the standard, this is an optimization which many users
want now, and which will help with benchmarks -- every sophisticated
C++ compiler should have this capability.  The ARM and the C++ standards
committees' working paper do not explicitly give a green light to this
optimization.  But the issue has been raised in the committee, and
discussion indicates that committee members generally consider the
optimization valid.  There's a good chance that the final standard
will sanction this return value optimization.

Also, your compiler may have a "strict ANSI" command line switch,
and you've got to decide whether enabling that switch will disable the
optimization.  That choice depends on what you mean by "strict ANSI"
at this time, when there is no official C++ standard.
--
Prescott K. Turner, Jr.
Liant Software Corp. (developers of LPI languages)
959 Concord St., Framingham, MA 01701 USA    (508) 872-8700
UUCP: uunet!lpi!pkt                          Internet: pkt@lpi.liant.com




Author: b91926@fnclub.fnal.gov (David Sachs)
Date: 3 Nov 1993 19:03:40 GMT
Raw View
In article <tjmCFvxzx.4FE@netcom.com>, tjm@netcom.com (Thomas J. Merritt) writes:
...
|> The question is then, can (&returnvalue == &t) ever be TRUE?
|>
...


Yes, the copy constructor (and the corresponding destructor) for a return value are allowed to be bypassed EVEN IF THEY HAVE SIDE EFFECTS THAT WOULD CHANGE PROGRAM BEHAVIOR.




Author: sg3235@sw1sta.sbc.com (Stephen Gevers)
Date: 2 Nov 93 15:15:40 GMT
Raw View
In article <rfgCFsIEw.CD0@netcom.com> rfg@netcom.com (Ronald F. Guilmette) writes:
>In article <2a6n69$1c9@s.ms.uky.edu> jedwards@ms.uky.edu (Jonathan Edwards) writes:
>>Given a class HugeInt and the following function
>>
>>friend HugeInt operator-(const HugeInt& LHS,const HugeInt& RHS)
>>{
>>  HugeInt t = LHS;   // Assume HugeInt::HugeInt(const HugeInt&) exists
>>
>>  return (t -= RHS); // Assume HugeInt::operator-=(const HugeInt&) exists
>>}
>>
>>is it legal for a C++ compiler to eliminate the variable t and the
>>associated call to the copy constructor?
>
>Those are two separate questions.
>
>I don't know of any rule which would give compilers permission to "eliminate"
>the variable.
>
>I seem to recall a rule which would permit the elimination of the copy
>constructor call however.
>
>--
>
>-- Ronald F. Guilmette, Sunnyvale, California -------------------------------
>------ domain address: rfg@netcom.com ---------------------------------------
>------ uucp address: ...!uunet!netcom.com!rfg -------------------------------

This thread was going on in comp.std.c++.  The C++ compiler can not eliminate
the variable.  The rule which would permit the elimination of the copy
constructor has to do with the elimination of temporary variables.  `temporary'
in this sentence means an un-named variable created by the compiler in
order to implement some construct.  The ARM discusses the creation/destruction/
and elimination of temporary variables in 12.1.1c:

 The fundamental rule is that the introduction of a temporary object
 and the calls of its constructor/destructor pair may be eliminated if
 the only way the user can detect its elimination or introduction is
 by observing side effects generated by the contructor or destructor
 calls (12.1, 12.4)

This is from the first edition of the ARM (Ellis/Stroustrup).  The index in
"The C++ Programming Language" second edition refers to page 571 for the
elimination of temporaries.  However, I was not able to find anything specific
on this issue.  The bottom line is that the variable "t" in the above example
is NOT a temporary and cannot be eliminated.

Stephen Gevers
sg3235@shelob.sbc.com




Author: kanze@us-es.sel.de (James Kanze)
Date: 2 Nov 93 20:29:05
Raw View
In article <rfgCFsIEw.CD0@netcom.com> rfg@netcom.com (Ronald F.
Guilmette) writes:

|> In article <2a6n69$1c9@s.ms.uky.edu> jedwards@ms.uky.edu (Jonathan Edwards) writes:
|> >Given a class HugeInt and the following function
|> >
|> >friend HugeInt operator-(const HugeInt& LHS,const HugeInt& RHS)
|> >{
|> >  HugeInt t = LHS;   // Assume HugeInt::HugeInt(const HugeInt&) exists
|> >
|> >  return (t -= RHS); // Assume HugeInt::operator-=(const HugeInt&) exists
|> >}
|> >
|> >is it legal for a C++ compiler to eliminate the variable t and the
|> >associated call to the copy constructor?

|> Those are two separate questions.

|> I don't know of any rule which would give compilers permission to "eliminate"
|> the variable.

|> I seem to recall a rule which would permit the elimination of the copy
|> constructor call however.

I believe what Ron is referring to is the sentance in section 12.6.1
of the ARM: "Typically, that call of a copy constructor can be
eliminated."  This is admittedly rather vague; what does typically
mean, and how does the compiler "eliminate" the constructor.  (A
straightforward reading would say, it just suppresses calling it, but
common sense would suggest that if a call to the constructor is
eliminated, the compiler would also have to eliminate a call to the
destructor somewhere.)

This question is treated in somewhat more depth in section 12.1c.
Note that this is part of the commentary, and not part of the
reference manual itself.  I would suggest that given good sense, and
the commentary, that we interpret the ARM to mean that temporary
variables may be eliminated, and not just calls to the constructor.
(I actually prefer the idea of stating that they may be aliased to
something else.  But this is my wording, and not that of the ARM.)  I
would hope that the wording that finally makes it into the standard
would reflect this.  Common sense and commentary are fine for
reference manuals, but may not be used when reading a standard.
--
James Kanze                             email: kanze@us-es.sel.de
GABI Software, Sarl., 8 rue du Faisan, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                   -- Beratung in industrieller Datenverarbeitung




Author: tjm@netcom.com (Thomas J. Merritt)
Date: Tue, 2 Nov 1993 22:19:08 GMT
Raw View
In article <2335@swuts.sbc.com> sg3235@sw1sta.sbc.com (Stephen Gevers) writes:
|In article <rfgCFsIEw.CD0@netcom.com> rfg@netcom.com (Ronald F. Guilmette) writes:
|>In article <2a6n69$1c9@s.ms.uky.edu> jedwards@ms.uky.edu (Jonathan Edwards) writes:
|>>Given a class HugeInt and the following function
|>>
|>>friend HugeInt operator-(const HugeInt& LHS,const HugeInt& RHS)
|>>{
|>>  HugeInt t = LHS;   // Assume HugeInt::HugeInt(const HugeInt&) exists
|>>
|>>  return (t -= RHS); // Assume HugeInt::operator-=(const HugeInt&) exists
|>>}
|>>
|>>is it legal for a C++ compiler to eliminate the variable t and the
|>>associated call to the copy constructor?
|>
|>Those are two separate questions.
|>
|>I don't know of any rule which would give compilers permission to "eliminate"
|>the variable.
|>
|>I seem to recall a rule which would permit the elimination of the copy
|>constructor call however.
|>
|>--
|>
|>-- Ronald F. Guilmette, Sunnyvale, California -------------------------------
|>------ domain address: rfg@netcom.com ---------------------------------------
|>------ uucp address: ...!uunet!netcom.com!rfg -------------------------------
|
|This thread was going on in comp.std.c++.  The C++ compiler can not eliminate
|the variable.  The rule which would permit the elimination of the copy
|constructor has to do with the elimination of temporary variables.  `temporary'
|in this sentence means an un-named variable created by the compiler in
|order to implement some construct.  The ARM discusses the creation/destruction/
|and elimination of temporary variables in 12.1.1c:
|
| The fundamental rule is that the introduction of a temporary object
| and the calls of its constructor/destructor pair may be eliminated if
| the only way the user can detect its elimination or introduction is
| by observing side effects generated by the contructor or destructor
| calls (12.1, 12.4)
|
|This is from the first edition of the ARM (Ellis/Stroustrup).  The index in
|"The C++ Programming Language" second edition refers to page 571 for the
|elimination of temporaries.  However, I was not able to find anything specific
|on this issue.  The bottom line is that the variable "t" in the above example
|is NOT a temporary and cannot be eliminated.

I agree with this analysis.  One question remains though.  Can the copying
of t to the return value of operator- be eliminated by by merging t with
the return value.  In other words, assume that we have.

HugeInt::HugeInt(HugeInt const &x);
void HugeInt::operator-=(HugeInt const &x);

HugeInt operator-(HugeInt const &l, HugeInt const &r)
{
    HugeInt t = l;  // 1
    t -= r;   // 2
    return t;   // 3
}


1) must map to (&t)->HugeInt::HugeInt(l);

2) must map to (&t)->HugeInt::operator-=(r);

3) must map to
 if (&returnvalue != &t)
     (&returnvalue)->HugeInt::HugeInt(t);

The question is then, can (&returnvalue == &t) ever be TRUE?

I realize that the original code was not written to readily take advantage
of this optimization.

TJ Merritt
tjm@netcom.com