[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: |
Thu, 8 Mar 2018 10:18:18 +0100 |
> On 8 Mar 2018, at 00:33, Frank Heckenbach <address@hidden> wrote:
>
>>> Sure, it's not required (nothing about the C++ mode is), but it
>>> might be convenient for the user as it avoids a trap. I have a
>>> number of such rules in my grammars, and if you hadn't mentioned it,
>>> I'd have been caught by this, not even at compile-time, but at
>>> runtime. (Though such a bug would probably be rather obvious and
>>> easy to fix in all places, not the end of the world.)
>>
>> It should complain if not having a not supported semicolon.
>
> Not sure I follow you here. If I have a rule like "foo: bar;" where
> foo and bar have the same (non-void) type, the C skeleton does
> "$$ = $1"; the standard C++ skeleton just default-initializes $$
> (so it will not be undefined, just empty). My patch does
> "$$ = std::move ($1)" (effectively).
We are speaking about different things here: In Yacc grammar one drop the ";".
>> It might be good to be able to change container, C++ perhaps sues
>> a deque for stack as copying might be expensive.
>
> 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
>>>> Using inline functions for the actions might do it. The compiler
>>>> can then remove the inlines, but the moves should be still applied
>>>> correctly. Or maybe not, depending on how the C++ standard is
>>>> written.
>>>
>>> AFAIK, it allows for (and modern compilers do) automatic moving for
>>> the return value only. So inline functions would help in cases such
>>> as the default action ("$$ = $1", if "$$ =" was replaced by "return"
>>> and "$1" was a function parameter), and similar cases such as
>>> "$$ = $2" (which typically occurs in rules such as '(' expr ')')
>>> where a default action doesn't help.
>>
>> 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 think it's an interesting idea, also for syntactic reasons:
>>> Writing "return" instead of "$$ =" seems more natural (though of
>>> course, you have to watch out: "$$ =" can be followed by other
>>> statements, "return" cannot, so Bison couldn't simply replace it,
>>> but a user can deal with it). Also functions could have named
>>> parameters (which you seem to prefer anyway) always instead of "$1"
>>> etc. So if I'd design Bison now, that's probably what I'd do. But
>>> given things as they are, this might be too big a change, both to
>>> implement, and for many users to adopt.
>>
>> I though of it just as an implementation, but whatever.
>
> 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.
>> [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, and the more advanced variation I used
turned out to be too complicated.
>
>> Where automatic objects can be used, that is better.
>
> ... indeed, most of the time, automatic objects or unique_ptr
> suffices for me and I prefer to use it.
A GC possibility is isolate object with known lifetime and register those with
pointers into the GC heap.
>>> 3. shared_ptr: Has the performance problems as I described.
>>
>> I don't recall this.
>
> 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.
>>>> Since C++17 now is available and supported by GCC7, std::variant would be
>>>> best to use.
>>>
>>> Agreed. It will require some changes to the code using it, but it
>>> will actually make it simpler.
>>
>> And more reliable, as the compiler developers pay attention to it.
>
> And more type-safe. std::variant checks more at compile-time that
> Bison's variant doesn't.
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.
- Re: C++11 move semantics, (continued)
- Re: C++11 move semantics, Hans Åberg, 2018/03/04
- Re: C++11 move semantics, Frank Heckenbach, 2018/03/04
- Re: C++11 move semantics, Hans Åberg, 2018/03/05
- Re: C++11 move semantics, Frank Heckenbach, 2018/03/05
- Re: C++11 move semantics, Hans Åberg, 2018/03/05
- Re: C++11 move semantics, Frank Heckenbach, 2018/03/05
- Re: C++11 move semantics, Hans Åberg, 2018/03/06
- Re: C++11 move semantics, Frank Heckenbach, 2018/03/06
- Re: C++11 move semantics, Hans Åberg, 2018/03/07
- Re: C++11 move semantics, Frank Heckenbach, 2018/03/07
- Re: C++11 move semantics,
Hans Åberg <=
- Re: C++11 move semantics, Frank Heckenbach, 2018/03/08
- Re: C++11 move semantics, Hans Åberg, 2018/03/09
- Re: C++11 move semantics, Hans Åberg, 2018/03/09
- Re: C++11 move semantics, Frank Heckenbach, 2018/03/09
- Re: C++11 move semantics, Hans Åberg, 2018/03/09
- Re: C++11 move semantics, Frank Heckenbach, 2018/03/09
- Re: C++11 move semantics, Hans Åberg, 2018/03/10
- Re: C++11 move semantics, Frank Heckenbach, 2018/03/10
- Re: C++11 move semantics, Rici Lake, 2018/03/10
- Re: C++11 move semantics, Hans Åberg, 2018/03/11