bug-bison
[Top][All Lists]
Advanced

[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 10:15:11 +0100

> On 9 Mar 2018, at 02:26, Frank Heckenbach <address@hidden> 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.

>>> Since std::stack moves instead of copying when possible, not quite
>>> so expensive. Also bison by default reserve()s 200 entries, and I
>>> think you rarely need a parser stack deeper than this, so this might
>>> be a theoretical problem.
>> 
>> The type std::stack is older, but some benefits of std::deque are mentioned 
>> here:
>>  http://en.cppreference.com/w/cpp/container/deque
> 
> I think you rarely need a parser stack deeper than this, so I still
> don't think that matters for Bison, or do you any such examples?

It might be remnant from the C parser.

> Anyway, while doing the C++11 changes in stack.hh, I now made it
> possible to set other containers. If it makes you happy. :)

Good.

>>>> Perhaps if it know that $1 expires, it can apply a move assignment.
>>> 
>>> It could do that if $1 is mentioned only once. In fact, I just
>>> checked my grammars and in almost all cases that's so (not counting
>>> a later "free ($1)" or "delete $1" which is part of the manual
>>> pointer management which would disappear with unique_ptr); for me
>>> that's because I prefer to keep my actions short and do all
>>> non-trivial work in subfunctions.
>>> 
>>> It's still not a silver bullet: Others might prefer longer actions
>>> that regularly mention $n more than once, and even I have at least
>>> one such rule, basically:
>>> 
>>> a: b c { $$ = $2.empty () ? $1 : combine ($1, $2); };
>>> 
>>> Here, moving from $1 would be safe in both places as only one is
>>> executed; moving from $2 is safe in the combine() call, not in the
>>> empty() call (but also not required, since empty() is a const member
>>> function). That's not too difficult for a programmer to see, but
>>> almost impossible for Bison to do automatically.
>>> 
>>> Of course, Bison could give up there (and possibly warn about it),
>>> and still do automatic moving in other situations.
>> 
>> I think it would be complicated, so just std::move for now.
> 
> 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.

>>> 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.

>>>> [GC]
>>>> 
>>>> I use it for dynamic polymorphism like in Scheme/Guile, where you
>>>> can't tell when the object expires.
>>> 
>>> shared_ptr also does it (and I used it where I need it), but ...
>> 
>> The std::shared_ptr is simplistic,
> 
> I think you're one of few people to call it that. :) It has a number
> of advanced features few people will ever use. The only thing I find
> lacking is a way to release the object, and AIUI that's intentional
> because of cross-thread optimization.

It would work in the setting I used, Scheme-like dynamic polymorphy, and it 
does not have release.

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.

>>> Lack of release method, so it would propagate throughout all my
>>> code. See first mail in thread.
>> 
>> 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?

>> You may do your own M4 files, and as Bison isn't development,
>> there is no risk for it to become outdated, and maybe get it
>> integrated later.
> 
> Seems so. I'm working on that now.

It does not hurt trying it.





reply via email to

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