-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
Passing a Document by-value to a function taking a Value is broken in c++11 #387
Comments
I'd say, this is the expected behaviour. Moving from a In your expression, the (temporary) allocator gets destroyed after the full expression; The The same happens in your first code snippet. This will likely break as well, depending on the details of Long story short: Never mix values from different (even implicit) allocators across Document TransformValue(Value v, Document::AllocatorType& alloc) {
Document d(&alloc);
v.Swap(d); // "move" v to d
// original body of the function
return d;
}
inline Document TransformValue(Document d) {
return TransformValue(std::move(d), d.GetAllocator());
} hth, Edit: Edited to add missing |
Thanks for your response. The problem is that Document is a subclass of Value, which suggests to the user that you can pass a Document where a Value is expected, which leads to using temporary variables like I did in my first example.
|
As reported in Tencent#387, silently moving a `GenericDocument` to a `GenericValue` can lead to object slicing and premature deletion of the owning allocator of the (surviving) `GenericValue`. To reduce this risk, prohibit move construction of a `GenericValue` from a `GenericDocument`.
I agree that with C++11 moves, there additional gotchas in the API. It might be a good idea to explicitly prohibit moving from a But the biggest issue here is the mixture of |
Such clarification on the implicit binding of |
Fixed by #391 |
…LCP license is undefined (absent property). The bug was due to the RapidJSON move semantics not copying the allocator in Value objects (only in Document objects) when return a function value. Works fine in function parameters, due to the stacking memory context. Without this fix, the GetType() function returns 16 (or some other weird value) instead of zero for kNullType enum, and isNull() returns false due to internal mismatch in the mask value. https://github.com/Tencent/rapidjson/blob/master/include/rapidjson/document.h#L1954 https://rapidjson.org/md_doc_tutorial.html#TemporaryValues Tencent/rapidjson#387 (comment)
If we have
This works (as far as I can tell):
But this causes really confusing problems:
I think it is because the temporary value returned by ParseDocument gets move-constructed into the argument to TransformValue, but the move is incomplete because it retains the allocator, so when that temporary is deleted, weird stuff starts happening to
v
insideTransformValue
.The text was updated successfully, but these errors were encountered: