RE: Custom error message for stack overflow in C++
August 11, 2021 at 4:54 pm
(This post was last modified: August 11, 2021 at 5:25 pm by HappySkeptic.)
(August 11, 2021 at 4:40 pm)FlatAssembler Wrote: Is it important whether I create the
inside the method, or can I writeCode:shared_ptr<AssemblyCode> assemblyCode=new AssemblyCode();
and only laterCode:AssemblyCode *assemblyCode=new AssemblyCode();
for the raw pointer to be automatically converted to the smart pointer upon returning? I have no idea how it works.Code:return assemblyCode
Yes, this will work (if the calling code assigns the function return value to a smart pointer), but it is bad form to mix smart pointers and raw pointers to the same object in a program. What if one piece of code holds onto the raw pointer, and another the smart pointer? The raw pointer will point to a dead object at some point, once the last smart pointer to the object disappears. By enforcing the return object to be a shared_ptr<>, you are making the contract that everyone should use the smart pointer only (yes, they can still pull out the raw pointer, but the user would know that is bad).
Using a smart pointer is just as easy as using a real pointer. The * (prefix) and -> (postfix) dereference operators are the same.
Part of your problem may be solved by using the C++ references in parameter passing, as I posted earlier. It is almost always a performance mistake to pass class objects (as opposed to simple numeric types or pointers) by copy instead of by C++ reference.
To further expand on the idea to "not mix smart pointers and regular pointers to the same object", consider this scenario:
Code:
shared_ptr<AssemblyCode> convertToInteger32(const TreeNode & node, const CompilationContext & context);
// assign the return code to the smart pointer. There is now only one smart-pointer "myCode" that is keeping the returned data alive.
shared_ptr<AssemblyCode> myCode = convertToInteger32(node, context);
// We can use the underlying object using normal de-reference.
cout << *myCode;
This is perfectly fine, but this should blow up (it may not, but this dereferences deleted memory).
Code:
shared_ptr<AssemblyCode> convertToInteger32(const TreeNode & node, const CompilationContext & context);
// I don't like smart pointers, so just grab the raw pointer.
AssemblyCode * myCode = &(*convertToInteger32(node, context));
// Oops, because my smart pointer return-code just got deleted from the stack, myCode points to a deleted object (as there are no more smart pointers pointing to it)
cout << *myCode;