monotone-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Monotone-devel] MM with temporaries


From: Nathaniel Smith
Subject: Re: [Monotone-devel] MM with temporaries
Date: Fri, 23 Sep 2005 02:23:21 -0700
User-agent: Mutt/1.5.9i

On Fri, Sep 23, 2005 at 09:16:36AM +0200, Christof Petig wrote:
> Nathaniel Smith schrieb:
> > I noticed .cvssync got a few lines like:
> >     MM(boost::lexical_cast<std::string>(i->time));
> > recently.  I'm pretty sure these can't possibly work?
> 
> This usage shows a problem: Musings on integer variables are not
> possible with the current system.

Yes.  You're supposed to define a function
  void dump(<type>, std::string & out)
if you find some new type that you want to MM() on.

time_t is a bit annoying here, since it is probably some standard
type, but we don't know which one.  So either we define dump(time_t),
and don't define dump(<any other arithmetic type>) (for fear of
hitting a one-definition-rule violation), or we don't define
dump(time_t) and do define dump(<every possible arithmetic type>).

Helpful of POSIX, really.

> What about a value storing musing variant? I certainly have use for it.

Could be done reasonably straightforwardly.  A solution where there
are two different forms, and you have to understand this somewhat
subtle C++ tricksiness to know which to use, and there's no way to
tell when you got it wrong (until monotone crashes instead of
reporting errors).

> > MM() ends up passing its argument to Musing(), which takes a const
> > reference argument and stashes it in a member variable const
> > reference.  Then, if an assertion triggers, it prints out the value of
> > that member variable.  In this case, it seems that will point to a
> > already-deleted temporary, and we'll crash or something...
> > 
> > Distressingly, the compiler gives no warning or anything for this.
> 
> The only way I know to make the compiler warn about this is to require a
> non const reference. (The usual way to require a non temporary argument
> IIRC).

Unfortunately, a core use case for MM is things like:
void apply_change_set(change_set const & cs, manifest_map & m)
{
  MM(cs);  // fails if MM requires a non-const reference
  ...
}

Oh, but wait... we instantiate a Musing<typeof(obj)> object.  If obj
is const &, then Musing storing a T& would still result in a const&
(I'm assuming const&& is the same as const& -- is this true?); but if
obj is an rvalue (and thus of non-reference type), then T& results in
a non-const reference, and assigning an rvalue to this fails.

Or something.  Just writing MM in the first place seriously pushed
the limits of my C++ evil tricks skills, this is beyond my depth :-).

> > Anyone know how a way to get the compiler to stop (or a least warn) on
> > such things, or alternatively how to make them actually work?  We
> > don't want to just unconditionally store a value copy instead of a
> > reference, because MM() needs to be very cheap when assertions are not
> > hit, and this would make it very slow...
> 
> If we manage to copy the value once it is const this would work
> transparently (I don't know how to accomplish this, the STL algo
> variants e.g. decide by class inheritance, perhaps a similar way is
> possible). Is there a gcc internal function or a macro which tells
> whether an expression is a lvalue?

I don't know.  Seems like there should be, but I didn't find it in a
quick skim through the manual.

-- Nathaniel

-- 
"Lull'd in the countless chambers of the brain,
Our thoughts are link'd by many a hidden chain:
Awake but one, and lo! what myriads rise!
Each stamps its image as the other flies"
  -- Ann Ward Radcliffe, The Mysteries of Udolpho




reply via email to

[Prev in Thread] Current Thread [Next in Thread]