-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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
R.5 and who decides necessity? (Prefer scoped objects, don't heap-allocate unnecessarily) #2221
Comments
Actually, I should have said I was most often using an initializer, not a copy/move constructor, as in " |
That still uses the move constructor. |
I don't know what you mean by "in error to call out this case a violating R.5 for an initializer?"
Maybe you mean using list-initialization syntax, but that's irrelevant, it doesn't change anything about the logic of the code. What the guideline suggests, and Visual Studio seems to be following, is that a local smart pointer where you don't explicitly do something with the heap object (e.g. transfer ownership of it elsewhere, out of the function) might as well be on the stack and not on the heap. But I agree that large objects are a valid reason to avoid the stack, and so maybe the guideline should have an exception for very large objects (for some value of large - presumably Visual Studio could use the same threshold it uses for warning you to put them on the heap). I think you could silence the complaint by adding a redundant |
[where you quoted me, there was a typo (mine): the word "a" should have been "as"] I didn't think your suggestion could work since the actual message from the compiler is
But I tried it (at the end of the function, after the last use of that smart pointer), and indeed, the warning disappeared. I wouldn't have guessed that could help, given the message. But thanks for the workaround anyway! |
Editors call: Thanks! Done. |
The way I interpret the message is that is's saying that you should do one of those things to make the compiler think you're "using" the smart ptr in some way. Since reset is one of the things it says to do, I guessed that calling |
So it's kind of a best-practice issue: should you always prefer local (stack-allocated) objects over smart pointers and putting them on the heap as suggested by R.5, or are very large objects better placed on the heap to avoid huge stack requirements from a function? I didn't find any discussion about this guideline. Might you think of other situations that could make heap-allocation seem "necessary", that this rule might not consider?
The reason I ask...
In cleaning up some code, I ran into numerous places where unusually large objects were being created on the stack as variables local to functions (in case you care, they were usually DAO objects -- this is some very old MFC code), and the compiler was suggesting I should consider putting them on the heap. Presumably, it can be very bad to have functions suck up huge chunks of the stack. But that warning was coming from Visual Studio's compiler, not the guidelines. Okay, I can do that. Most of these were something like "
TheBigType TheVar;
". I don't remember all the sizes the warning was reporting as what the function would require of the stack, but it was usually in the tens of kilobytes. I'm not sure what the threshold is for triggering that warning.So I converted these over to using something like "
auto pTheVar = std::make_unique<TheBigType>()
" -- usually accompanied by changing the uses ofTheVar.field
topTheVar->field
or the passing of&TheVar
to a called function to instead passpTheVar.get()
. After making such changes, then I got the guideline R.5 warning triggered by my call to make_unique: "Move, copy, reassign or reset a local smart pointer
" (even though it was actually an initializer, not any of the things in that list). The description for this warning points to guidelines R.5, "R.5: Prefer scoped objects, don't heap-allocate unnecessarily".Indeed, there doesn't seem to be much leeway on that, as if it's always preferable to put the object onto the stack when you can, instead of putting it on the heap. So these two "best practices" warning seem to be at odds with one another. But was Visual Studio's compiler in error to call out this case a violating R.5 for an initializer? Based on the description, it seems consistent with R.5. Or are these truly conflicting ideas, here (the other being the idea that you shouldn't have a function use "too much" stack space)?
The text was updated successfully, but these errors were encountered: