[Top][All Lists]

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

Re: C++11 move semantics

From: Hans Åberg
Subject: Re: C++11 move semantics
Date: Fri, 9 Mar 2018 23:38:39 +0100

> On 9 Mar 2018, at 22:59, Frank Heckenbach <address@hidden> wrote:
> Hans Åberg wrote:
>>>> We are speaking about different things here: In Yacc grammar one [can't] 
>>>> drop the ";".
>>> OK, but how is this relevant here?
>> An example of Bison not being Yacc.
> Obviously. As I said, nothing about the C++ mode is required for
> Yacc compatibility. It just seems gratuitous to me to drop the
> default action when it's so easy to implement. -- Actually, even
> easier now that I use std::variant; I was able to unify this code
> with the non-variant version to always do the default action when no
> user action is given, and always default-initialize $$ when there is
> one, in order to avoid any illusion that there is a pre-action, and
> the relavant code is now shorter than before.

Akim Demaille wrote the C++ parser, and he is not active now. I thought the 
default should have been there, and it is unclear to me why it isn't. Maybe 
there should be an option for the choice.

>>>>> so expensive. Also bison by default reserve()s 200 entries, and I
>> It might be remnant from the C parser.
> Even if so, it's still a good idea to keep it, so vector basically
> never actually needs to reallocate.

It depends on the grammar.

>>> I looked into the code. Just adding std::move seems rather easy, but
>>> finding out if a $n is mentioned several times might be tricky on
>>> the m4 level, might require changes to Bison itself.
>>> And the question remains what to do then. One possibility would be
>>> an option auto-move or such. If not set, std::move is not inserted;
>>> if set it's always inserted, but Bison warns if $n is mentioned
>>> several times.
>>> Then there might need to be a way to suppress this warning for
>>> individual cases which gets complicated again. Or there is no such
>>> way, and if needed, one has to work around it. That would work fine
>>> with my grammar -- for the few such rules as mentioned above I could
>>> just move $n to temporaries. But for grammars that have this more
>>> often, this might get cumbersome, so I'm not sure how useful such an
>>> option would be to others.
>>> Any ideas?
>> No ideas. I suspect moves are from the point of view just an
>> optimization, lacking features for application like this.
> Well, std::move works alright. The only rule to remember (which is
> obvious when you consider what moving means) is that you cannot move
> from the same thing twice. To a C++11 programmer, that's natural.
> The question is just if we can make Bison do that automatically, at
> least in most cases.

It is interesting to think about: the lifetime objects are known, but not 
regulated by the stack.

>>>>> I did so at first, but then I realized that Bison would have to
>>>>> replace "$$ =" with "return" which is dangerous as I said. So it
>>>>> would probably be easier in the long run to leave this to the
>>>>> programmer. (But again, I doubt this will be implemented.)
>>>> And maybe the C++ standard does not admit one relying on it.
>>> I think move on return (when the target is a local variable or
>>> parameter) is guaranteed in recent standards (C++14 or so).
>> Then it might be possible.
> Only for "$$ =" in the best case. IMHO it's only a few rules (such
> as "'(' expr ')'") that would really profit from this (apart from
> the default action which I've already covered), so I don't think
> that's worth the effort.

It might be too special to worry about, given the required effort.

>> It would be enough for just keeping track of the semantic value in
>> the parser. It is more optimal to do the deallocations by hand as
>> in the C parser if one wants to optimize.
> Well, that's what I've been doing so far, hope to change it. As I
> said, my parser can suffer a little inefficiency (though with move
> semantics, it won't even have to), but the rest of my program must
> not.

Then some reference count might suffice.

>>>> I am not sure why you need it in the parser. Just put the object
>>>> on the heap and use shared_ptr in the semantic value, but nowhere
>>>> else.
>>> That's exactly what I'd need a release method for when transferring
>>> objects from the parsed structures to the rest of the program.
>> Can't you use the shared_ptr::reset function?
> Nope, reset destroys the object. See the stackoverflow page I linked
> in my first mail for a discussion. There doesn't seem to be a "nice"
> way, and that seems to be intentional.

It seems shared_ptr [1] can use a deleter object, which might then be set to do 
nothing. Cf. function 3 in [2] and constructor 5 in [3].

Otherwise, I wrote a ref count class with a detach function. I have class 
functions that may return a reference to *this or make a new allocation, so the 
count had to be put in the class object and not the reference object. This is 
why shared_ptr wouldn't work, as it holds the count.

1. http://en.cppreference.com/w/cpp/memory/shared_ptr
2. http://en.cppreference.com/w/cpp/memory/shared_ptr/reset
3. http://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr

reply via email to

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