[Rivet] Dangerous casting to FinalState

Chris Pollard cpollard at cern.ch
Wed Jul 8 17:14:52 BST 2015


Hi all,

David and I just had a quick chat about this, and I think I finally
understand what is going on here. David, please say something if I don't
summarize our discussion correctly...

We both agree that the best thing to do is to have remainingFinalState()
return "const VetoedFinalState&", which is the actual type of the
underlying returned object. Currently it returns "const FinalState&". This
change *should* generate compile-time warnings when a user tries something
like

FinalState fs = zfinder.remainingFinalState();

because fs is being copy-constructed from a more complex class. @Frank, I
think this will also make your attached broken example work as expected.

The following will work correctly and, now that remainingFinalState()
returns the correct type, is hopefully what users will do if they
absolutely have to make a copy.

VetoedFinalState vfs = zfinder.remainingFinalState();

David's opinion (and he's convinced me, too) is that object slicing is an
inherent "feature" of c++ that is going to be very difficult to work
around, so just being careful with return types is the right way to deal
with it.

Please pipe in of course if you see any issue with this.

Chris

On Wed, Jul 8, 2015 at 9:27 AM, David Grellscheid <
david.grellscheid at durham.ac.uk> wrote:

> The sequence
>
>   Type label = foobar;
>
> always calls a copy constructor of Type, it _never_ calls operator=().
>
> If the copy constructor Type(Type) is not user-defined, it will be
> created implicitly.
>
> In your case, a FinalState(const FinalState &) will be created and used
> as long as the result type of zfinder.remainingFinalState() is a
> descendant of FinalState.
>
>   David
>
>
> On 08/07/15 09:14, Chris Pollard wrote:
> > but... going back to Frank's Example1: I don't see a
> > FinalState(Projection) constructor. Won't operator =(Projection) be
> > called in the first line of
> >
> >       FinalState remainder = zfinder.remainingFinalState();
> >       addProjection(remainder, "RFS");
> >
> > since no appropriate constructor exists? Or will some implicit copy
> > constructor be called not via operator=?
> >
> > Chris
> >
> > On Tue, Jul 7, 2015 at 9:52 PM, David Grellscheid
> > <david.grellscheid at durham.ac.uk <mailto:david.grellscheid at durham.ac.uk>>
> > wrote:
> >
> >     Maybe the confusion comes from the fact that
> >
> >       Foo a = 7;
> >
> >     does not call operator=(), but calls the constructor Foo(int). It's
> >     just a different way of writing a constructor. operator=() is only
> >     called here:
> >
> >       Foo a;
> >       a = 7;
> >
> >     I still haven't had a chance to look at it in detail, sorry!
> >
> >     See you,
> >
> >       David
> >
> >
> >
> >     On 07/07/2015 21:49, Andy Buckley wrote:
> >
> >         Hmm, I certainly implemented it hoping that code with copy
> >         assignments (as
> >         opposed to copy constructions, which should perhaps also be
> >         banned to
> >         forbid an alternative-syntax route to achieving the same
> >         misguided goal)
> >         would now fail to compile. I based that on some StackOverflow
> >         reading since
> >         I was short of time to make an explicit test case of my own.
> >
> >         I was *hoping* (and convinced from that reading) that it would
> >         not be legal
> >         for a private virtual method on a base class to be overloaded as
> >         public
> >         (and certainly not *automatically*) on a derived class. It would
> >         be a huge
> >         pain if those operators need to be *explicitly* private'd on
> >         every derived
> >         Projection.
> >
> >         Aaaaand back to holiday ;-)
> >         AB
> >
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.hepforge.org/lists-archive/rivet/attachments/20150708/502da3f1/attachment.html>


More information about the Rivet mailing list