-
-
Notifications
You must be signed in to change notification settings - Fork 69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use of destructed object in lager::lenses::getset #160
Comments
Looking at the code it seems like |
There is also an issue that as long as |
That is an excellent catch. I think one solution is to not move into the getter, which would anyway normally use const& for the data. There is a potential unnecessary copy in some set via an update of the projected value but not sure it matters in most practical scenarios. |
Hi, @arximboldi! My main concern right now is that 'get()' part of the lens is executed during the 'set()' operation. And I don't know how to fix that properly. I tried some deferred calculation approach, but it breaks unittests in multiple places. |
Here is my proof-of-concept implementation, though it breaks |
Hey @dimula73 ! Sorry I haven't got back in that PR, I need to look into it more deeply keep getting caught in other stuff. |
Basically, we shouldn't calculate the getter when we know that the value will be dropped. The patch partially fixes arximboldi#160, because now the getter is not called at all during the set operation. But the double-move can still happen when both, getter and setter calls are performed.
The patch ensures the following requirements: 1) When `view(lens, whole)` is called: * the setter lambda is neither called nor constructed. It avoid unnecessary copies of the 'whole' object. * the `whole` object is directly forwarded into the getter lambda, without any copies. 3) When `set(lens, whole, part)` is called: * no getter is called at the toplevel lens (which value was previously discarded). * on the lower lenses, the getter receives an 'lvalue' reference to the `whole` object, and setter receives an 'rvalue' reference to the `whole` object. It ensures that there is no double-move problem. Fixes arximboldi#160
The patch ensures the following requirements: 1) When `view(lens, whole)` is called: * the setter lambda is neither called nor constructed. It avoid unnecessary copies of the 'whole' object. * the `whole` object is directly forwarded into the getter lambda, without any copies. 3) When `set(lens, whole, part)` is called: * no getter is called at the toplevel lens (which value was previously discarded). * on the lower lenses, the getter receives an 'lvalue' reference to the `whole` object, and setter receives an 'rvalue' reference to the `whole` object. It ensures that there is no double-move problem. Fixes arximboldi#160
The getter argument should be const-ref for now See this bug-report: arximboldi/lager#160
Hi!
I have found a weird issue in
lager::lenses::getset
. It looks like both lambdas acceptstd::forward<decltype(p)>(p)
, which causes the object to be moved twice. To make this happen, both getter and setter functions should accept a normal object, not a reference.Example code:
I'm not sure what is the best way to fix that. The simplest solution could be to make a copy of the object in
lager::lenses::getset
, which doesn't look like the best solution. Perhaps it is possible to implementgetset
routine without lambdas and avoud this extra copy?The text was updated successfully, but these errors were encountered: