[Top][All Lists]

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

Re: C++11 move semantics

From: Frank Heckenbach
Subject: Re: C++11 move semantics
Date: Tue, 06 Mar 2018 00:24:51 +0100

Hans Åberg wrote:

> > On 5 Mar 2018, at 18:15, Frank Heckenbach <address@hidden> wrote:
> > 
> > Let's see if I can add "$$ = std::move ($1)" as a default action in
> > my patches. (Not as a pre-action as in C, that would be wrong with
> > move, only as a default action when no user action is supplied.)
> That might be OK in this special case.

No special case, I implemented it fully generally in the C++11
template (my previous patch).

> > So I see no reason why it shouldn't be done by default, especially
> > since in C that's not a Bison quirk, but actually a Yacc feature.
> I got the impression it might be complicated to implement.

I had feared so, but as you can see, it wasn't. (And it would get
even easier with std::variant.)

> > That's unrelated. std::vector does all the std::move's it needs
> > internally.
> This f you might want to avoid tweaking the M4 file and just change the 
> container.

Again, changing the container does not help. The parser needs move
semantics in other places, and once they're implemented (which I
did), vector just works!

> > In user actions, one needs std::move regardless, e.g.
> > "$$ = std::move ($1)" (like the default action) or something like
> > "$$ = build_something (std::move ($1), std::move ($2))" with some
> > user-defined build_something function. That's not poor design; such
> > code is expected when using move-only types. But again, the user
> > actions are not the issue, bison can't do anything there anyway
> > (except for the default action, see above). The required moves
> > within the parser are the problem.
> It seems to be forced that way, but ideally, the moves should be hidden away 
> in containers.

We're talking about user-actions here. To them, $$, $1, etc. do and
should behave just like varibles. (That $1 is an element of a
container is irrelevant, and again, there's no difference between
vector and deque in this regard.) The user action might use them
twice ("foo ($1); bar ($1);"), so always moving would be wrong. It's
up to the user to move when wanted. And it's not really a problem --
with a move-only type, the compiler will complain when you forget

> > GC doesn't call destructors, does it?
> One can a could of different things with the Boehm GC, register
> finalizers, and it also a deallocation function.

If you have to register them explictly, all the beauty of RAII is

> >> and shared_ptr might be an alternative.
> > 
> > Not for me (in many cases), as I explained.
> You will have to explain it again.


Though I don't understand why we need to argue this. Others on the
list have requested move semantics, and you put some work into it
yourself, so it seems obvious they're useful (just like most modern
C++ is based on them).

> >> I was thinking on the deprecated auto_ptr.
> > 
> > Oh, that! I think it's widely agreed that auto_ptr was a design fail
> > (just a hack to try to support moving pre-C++11). Too dangerous to
> > accidentally move, and it must not be used with standard containers:
> > https://stackoverflow.com/questions/111478/why-is-it-wrong-to-use-stdauto-ptr-with-standard-containers
> And it was probably the one that failed with $$ = $1.

That may be the case, but the problem then is with auto_ptr. In fact
"$$ = $1" will also fail with unique_ptr, but at compile-time.
"std::move" (or the current variant's internal move) works, but of
course, it will destroy $1, that's why it can only be done if
there's no explicit action (unlike in C). That's what my patch does.

> >> It is not difficult to hack the M4 file, but if one writes the
> >> parser, not actively develops for awhile, and Bison changes it,
> >> then that may turn out be a hurdle say in a few years time.
> > 
> > Exactly. That's why I hoped to see a maintainer here.
> I can't help you. The CC you removed was to one of them.

I didn't remove any CC. You CC'ed one (short) mail to Paul Eggert
which just said that Akim Demaille has not been active for some time
now. I hadn't replied to that mail, but to the main thread which was
not CC'ed.

> >> I do not remember, so you would have to search the list archives. I am 
> >> just saying there might a risk there.
> Maybe "C++17" then.

Found it, I suppose that's what you mean:


Indeed, it seems it doesn't work with $<...>. I didn't notice
because I never use this feature. (When I need a temporary value
from a mid-rule action, I turn it into a nonterminal instead; seems
more type-safe to me, no need to manually match the type on
assignment and usage.)

Bison's variant implementation really breaks down here. One could
work around it with some extra code to keep track of the dynamic
type of $<...>, but that gets really close to reimplementing
std::variant, so it seems rather pointless. So std::variant is the
way to go, at least in the long run. (As I said, I don't use gcc7
set, but I don't require $<...>, so for now I'll be fine with
Bison's variant.)


reply via email to

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