Topic: Guru of the Week #6: Solution


Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/04/10
Raw View

Valentin Bonnard <bonnardv@pratique.fr> writes:

|>  Why is operator= a special case in this respect ?
|>
|>      T () = T ();
|>
|>  isn't valid (as far as I know), but
|>
|>      T () += T ()
|>
|>  is. Is there a rationnal for the introduction of such
|>  a special case ?

If T is a built-in type, neither are valid.

If T is a user defined type, the validity of both depends on the
operator= or operator+= provided.  If there isn't one, they are illegal.
If there is one, but it is a global function taking a non-const
reference for the left hand side, it isn't legal.  If the operator is a
member function, or takes a const reference on the left hand side, they
are legal.

The main difference stems from the requirements concerning operator=.
First, it cannot be a global function, so one of the cases disappears.
Second, if you don't define an operator=, the compiler provides you with
one (which makes T() = T() legal!).

Why the difference?  Well, the compiler *must* provide an operator= if
you don't, for reasons of C compatibility.  (You can assign struct's in
C.)  And if you were allowed to provide a global operator=, the compiler
couldn't know a priori whether you'd provided one or not.

The results of the matter are that, for normal cases (where both
operator= and operator+= are members), T() = T() is perfectly legal, and
T() += T() is legal if the operator+= is provided.  Except, of course,
for built-in types.

--
James Kanze      home:     kanze@gabi-soft.fr        +33 (0)1 39 55 85 62
                 office:   kanze@vx.cit.alcatel.fr   +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
     -- Conseils en informatique industrielle --
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/04/06
Raw View
[I followup Herb Sutter and ask a tecknical question at the
same time;
moderator: if you can't handle the cross-post, just separate
           the posts;
posters: choose the right group to followup]

{ I don't think it's fair to ask the moderators to `just separate
  the posts'; depending on the moderator's setup, this may not be
  a trivial task. -vdv }

Herb Sutter wrote:
> [Warning: This solution contains points that some may find arguable.]

Yes

> 1.  Since the point object is passed by value, there is little
>     or no benefit to declaring it const.
>
> >       Point GetPoint( const int i )    { return points_[i]; }
>
> 2.  Same comment about the parameter as above.  Normally const
>     pass-by-value is unuseful and misleading at best.

Has argued, it's arguable.

If the function contain a loop which is runned 100000 times
or if it's called 100000 times it can interresting to
make i const has it help the optimiser.

> 4.  (Arguable.)  Return-by-value should normally be const for
>     non-builtin return types.  This assists client code by
>     making sure the compiler emits an error if the caller
>     tries to modify the temporary (for example,
>     "poly.GetPoint(i) = Point(2,2);"...

which isn't possible anyway so the argument doesn't hold
the way it's written.

[The std question:]
Why is operator= a special case in this respect ?

    T () = T ();

isn't valid (as far as I know), but

    T () += T ()

is. Is there a rationnal for the introduction of such
a special case ?

>     after all, if this was
>     intended to work, GetPoint() should have used
>     return-by-reference and not return-by-value in the first

The user of the class can want to use the temporary directly.
I don't like the idea taht it's const (I don't like the way
C++ define that anyway).

>     place, and as we will see later it makes sense for GetPoint()
>     to return a const value or a const reference since it should
>     be usable on const Polygon objects in operator+()).
>
>     Note:   Lakos (pg. 618) argues against returning const
>             value, and notes that it is redundant for builtins
>             anyway (for example, returning "const int"), which
>             he notes may interfere with template instantiation.
>
>     [Guideline] When using return-by-value for non-builtin
>                 return types, prefer returning a const value.

--

Valentin Bonnard
mailto:bonnardv@pratique.fr
http://www.pratique.fr/~bonnardv (Informations sur le C++ en Francais)

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: herbs@cntc.com (Herb Sutter)
Date: 1997/04/08
Raw View

BAD MSG:
<pgpmoose.199704061722.16795@isolde.mti.sgi.com>
-Newsreader: Forte Agent 1.0/32.390
X-Auth: PGPMoose V1.1 PGP comp.std.c++
 iQBVAwUBM0kxLEy4NqrwXLNJAQErOwH/VO2zBGJLMm3E+s+iL5A7XA8jSefUB/if
 9Dd8d+bWL03AC7UQ53O1m4vpPZokVsHnMopXBPz+KlSR3FhXXtjnwg==
 =TdwQ

Valentin Bonnard <bonnardv@pratique.fr> wrote:
>Herb Sutter wrote:
>> [Warning: This solution contains points that some may find arguable.]
>
>Yes
>
>> 1.  Since the point object is passed by value, there is little
>>     or no benefit to declaring it const.
>>
>> >       Point GetPoint( const int i )    { return points_[i]; }
>>
>> 2.  Same comment about the parameter as above.  Normally const
>>     pass-by-value is unuseful and misleading at best.
>
>Has argued, it's arguable.

Actually, this wasn't one of the points I considered arguable. :-)  Although
there has been some discussion about it in clcm, I believe the consensus is
that the above advice stands for function declarations.

>> 4.  (Arguable.)  Return-by-value should normally be const for
>>     non-builtin return types.  This assists client code by
>>     making sure the compiler emits an error if the caller
>>     tries to modify the temporary (for example,
>>     "poly.GetPoint(i) = Point(2,2);"...
>
>which isn't possible anyway so the argument doesn't hold
>the way it's written.

Why not?  If GetPoint() returns a non-const temporary, that's legal code.
Consider:

struct Point { Point( int, int ) {} };

      Point f() { return Point(1,1); }
const Point g() { return Point(1,1); }

int main()
{
    f() = Point(2,2); // OK
    g() = Point(2,2); // error
}

>[The std question:]
>Why is operator= a special case in this respect ?
>
>    T () = T ();
>
>isn't valid (as far as I know), but
>
>    T () += T ()
>
>is. Is there a rationnal for the introduction of such
>a special case ?

I don't follow.  Both operator= and operator+= should always return a
reference to *this.  However, operator+ (for example) knows it is returning a
temporary and therefore should return a const temporary to let the compiler
emit an error if the user tries to modify it.

>>     after all, if this was
>>     intended to work, GetPoint() should have used
>>     return-by-reference and not return-by-value in the first
>
>The user of the class can want to use the temporary directly.
>I don't like the idea taht it's const (I don't like the way
>C++ define that anyway).

Can you give an example?

---
Herb Sutter (mailto:herbs@cntc.com)

Current Network Technologies Corp. (http://www.cntc.com)
2695 North Sheridan Way, Suite 150, Mississauga ON Canada   L5K 2N6
Tel 416-805-9088   Fax 905-822-3824
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]

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