[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: Sun, 4 Mar 2018 22:50:15 +0100

> On 4 Mar 2018, at 22:19, Frank Heckenbach <address@hidden> wrote:
>>>> That version is OK. In the past, there was a C hack where the
>>>> default rule action was implemented by always doing $$ = $1, which
>>>> does not work with unique_ptr.
>>> I remember it used to do this before every action, even
>>> user-supplied actions, which was questionable.
>> OK in C, as it just copied the chunk.
> It would work in C, but users were advised not to rely on it.

No problem in C, as there are no copy constructors, just an overhead.

>>> But now I see, it
>>> doesn't do it at all, even with no user action. This seems to
>>> contradict the documentation
>>> https://www.gnu.org/software/bison/manual/html_node/Actions.html
>>> : If you don't specify an action for a rule, Bison supplies a
>>> : default: $$ = $1
>>> Is this intentional? If so, I'd have to add this action to some of
>>> my rules (in some cases with std::move). Good to know this now.
>> The way it should work now is providing if no explicit action is
>> given, otherwise not. Before, one always got it first, before the
>> eventual explicit action.
> That's what I thought too, but it doesn't seem to (and it wouldn't
> work with move-only types without std::move). It just seems to leave
> $$ unset (i.e. default-constructed) without an explicit action.

If you don't have an {...}, one should get $$ = $1. Personally, I don't rely on 
it, one reason is that I have more that one field in the semantic value. So a 
rule may look like:
    "name"[x] { $$ = ... $x.name ...; }
   | ...

Such variable naming is useful, avoiding having to keep track of the numbering.

>>> But anyway, the issues with unique_ptr and other move-only types are
>>> not mainly in the actions, but more in the generated code, starting
>>> with the make_FOO functions. Again, I don't see that the default
>>> versions in 3.0.4 support moving. Do you use another version?
>> No versions support moving, and 3.0.4 may be the latest. The
>> objects must be locations where it is expires, and that may not
>> work well with the Bison parser.
> Sorry, I don't quite understand your last sentence.

Even with a type support move constructors, the $$ and $k are not in positions 
where they will be invoked.

>>> (In fact, after my patches, I could remove the
>>> assignment operator from lalr1.cc. It was specially provided for
>>> vector::push_back, but is no more needed then.)
>> The Bison distributed skeleton file might change, and then yours become does 
>> not benefit from that.
> That's the problem: If Bison isn't developed, the skeleton file
> won't change, so I could (and would have to) keep my changes
> locally. But if it's developed and the skeleton file changes, I'd
> like my version to benefit, so I'd like to get it integrated. If
> Bison doesn't want to require C++11, my changes could be made
> conditional, either with #ifdef or with m4 macros. I'd be willing to
> work on that, but only if there's a point to it, i.e. if Bison is
> still maintained.

That is complicated. I jave tried it, so I decided to not do it.

>>> But again, what/where is this "untyped grammar C++ parser" you
>>> mentioned? I might try it, but I don't see it anywhere.
>> Just don't use %union.
> Actually, I'm not using %union, but "%define api.value.type variant"
> just like in the calc++ example.

There was a report on som issue with that. So it would be better no using it 

> Do you mean using an "untyped"
> semantic type, i.e. a kind of variant manually? But it would still
> need to be copyable, or does moveable suffice then?

The types one writes in the grammar selects fields in the %union or variants. 
For C++ it seems safest to not use the variants it has in view of that issue. 

>>> And when you say "the typed does not work properly", are you
>>> referring to lalr1.cc? What doesn't work? With the calc++ example
>>> I saw no problems, but it's just a toy, of course. So if there are
>>> serious problems, I'd like to know about them before I try to port
>>> my parser.
>> It was an issue with the variants.
> Well, I read variant.hh, and I did't spot any serious problems.
> Whatever the issue was, maybe it's fixed now.

I don't think so, in view of that the C++ parser isn't developed. You might try 
searching the archives.

> A questionable decision is that it doesn't keep track of the active
> variant (the typeid is stored just for debugging) and relies on
> external knowledge. It works, but makes other code more complicated,
> e.g. implementing move constructor/assignment for basic_symbol. If
> the variant itself had a move (and optionally, copy)
> constructor/assignment, this would be more straightforward.
> In the long run, it might be preferable to switch to C++17 variants,
> but ATM I don't actually use C++17 yet (maybe next year).

GCC7 supports C++17, but as the Bison C++ parser isn't developed, that does not 

>>> I think we agree here. If I'd always use shared_ptr, I wouldn't have
>>> any problems since it's copyable. But as I said, I want to use
>>> unique_ptr (or other move-only types) in most cases, that's why I
>>> need move semantics.
>> You might start with unique_ptr to see if it suffices. There is no
>> Bison support for move semantics to be expected any time soon.
> I do want to start with unique_ptr, but unique_ptr requires move
> semantics, that's just the point.

I though the copy constructor moves the pointer just as well. But try 
shared_ptr then, the difference is just some overhead.

reply via email to

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