Add a const here, delete a const there
randomascii.wordpress.com
randomascii.wordpress.com
I believe the site has some malware injected in it. At least the mobile version of it. After a few second it redirected me to some site with a fake Facebook skin.
const is for enforcing correctness by the compiler. It tells the compiler about intent, but it doesn't give the compiler any extra information that it can use for optimizing.
Example: If you mark a member function as const then the compiler knows that you can't modify member variables. However the compiler won't use that to optimize the function - what it will use is its own data flow analysis that independently shows that you aren't modifying any member variables.
The distinction becomes important if you call some non-member function whose definition is not visible. At that point the compiler has to assume that that function might modify the object, though a separate cached pointer. So, the fact that the member function is const becomes useless as soon as the the compiler can't analyze code flow anymore.
I believe.
Consider the amount of optimizations seen in the video from CppCon 2016: https://www.youtube.com/watch?v=zBkNBP00wJE
Jason Turner, the presenter, is writing code a few lines at a time and cross compiling for the Commodore 64. He shows his assembly at many steps of the way and shows how many functions are completely elided when const (and later constexpr) are used correctly.
There are a ton of other good talks from CppCon 2016 including one about const and what optimizations it makes possible and several about how compilers are more willing to "break" code that is non-compliant by making its behavior undefined. None of it really shocking or new, unless you have been writing to one compiler implementation instead of to the standard.
I think you should focus more on giving concrete examples instead of making snide comments.
And, I'm not going to watch an eighty minute video in order to find out what you are talking about. Specific examples would be appreciated.
I agree that tagging globals as const can help the optimizer. If that is what you were talking about then I have no disagreement. However I have seen many people who expect speed wins when they tag member functions as const, or local variables as const. In those cases it is rare for 'const' to improve code-gen.
The instant where the const keyword removes 95+% of the generated machine code is just after 28:00, but you should watch from at least a few minutes before that to establish context. That wasn't a global he put it on, but it wasn't a member variable either.
I recommend watching the whole talk, because the whole thing is pertinent to what optimizing can and cannot do. Because the speaker wants to get modern software onto an old machine he works around tight constraints while getting all of C++17. If you choose not to ignore something that you have expressed an interest in and is pertinent then you are doing something far worse than being rude and you are doing it to yourself.
Go benchmark you code, I have benchmarked mine. Putting const everywhere applicable helps even back in the pre-C++11 days. I state again not trusting and working with your optimizing compiler is simply an old an outmoded way of thinking.
The C++ standard doesn't mandate this, but good toolchains do put constant data in a separate read-only segment.
I just can't believe that one of the biggest monolithic organizations with unlimited budgets and decades of experience developing tools for their own platform(!!) would make such careless mistakes or miss out on rather obvious optimizations. And it also sickens me that random devs out there are wasting hours of their lives doing completely unpaid MS product QA work. At least when jobs are outsourced to the third-world, the laborers are paid something.
I've never considered that const might have a performance benefit (and mostly just use it as a compile time check). But will consider it in the future.
Would be interesting to see performance benchmarks for the changes made here, as well as applying const in general.
Usually you don't. You just tag your const globals as such and then get on with your day. Once you develop the habit the cost is zero so measuring the benefits isn't necessary.
Is this more of a whole program measured X% regression on some perf benchs, or specific target cases where the codegen is notably worse ?
My recent changes have made the comparison tougher for clang-cl by making the VC++ binaries smaller :-)
As for this comment of yours:
> I can't imagine a single reason to tell people not to use const instance fields.
That's weird, did you not read the blog post? It literally gave you a reason not to, you don't need to imagine anything. If you don't think it's a compelling reason then that's another story, but it's a valid reason.
More importantly, I've never seen an example where adding const would ever decrease CPU performance by any amount at all (other than compiler bugs, which can ruin any language feature). Accordingly, my personal recommendation is that everything that can be const should be. It's an easy thing to do that may help and definitely won't hurt.
> That's weird, did you not read the blog post? It literally gave you a reason not to, you don't need to imagine anything. If you don't think it's a compelling reason then that's another story, but it's a valid reason.
That's an outright compiler bug, not a general language reason. Obviously, it's a valid caveat if you're using that specific compiler and care about that edge case, but it's hardly a general argument.
Uh, that wasn't an instance field, was it? https://codereview.chromium.org/2608823002/diff/20001/third_...
> That's an outright compiler bug, not a general language reason.
It's not a bug, just a missed performance optimization. The code behaves correctly.
And I was merely responding to your comment, "I can't imagine a single reason to tell people not to use const instance fields."
The underlying language reason I have for it is not something you may agree with, but it's that it Seems Wrong (TM) to me for the fields of a class to dictate how the class's instances can be constructed or assigned to. Again, I don't claim I can convince you here. It just seems like poor design to me, and it's given me trouble so many times without once actually providing me a benefit. So it's a reason. YMMV.
Fair point, I was indeed being insufficiently precise. That code is a typical example of how const helps performance, concrete performance gains from applying const to instance fields in particular are much rarer in practice.
> It's not a bug, just a missed performance optimization. The code behaves correctly.
I think the MSVC devs classify it as a codegen bug since the cause is a logic error in the optimizer. The code does behave correctly, but it's reasonable to expect that optimization to happen, and it does in GCC / clang. My point here is simply that in this case MSVC is the outlier, therefore the example does not constitute a general argument against using const in this context.
> The underlying language reason I have for it is not something you may agree with, but it's that it Seems Wrong (TM) to me for the fields of a class to dictate how the class's instances can be constructed or assigned to.
I happen to have the opposite preference, namely that if you have constant data in a struct, it makes sense to say so at the declaration site for clarity. Regardless, it's a perfectly reasonable stylistic preference. I only argued against it because the phrase "NEVER have const instance fields. Ever." seems much too strong for what's ultimately a subjective choice. In doing so, however, I may have erred in the opposite direction and made overly strong statements myself. Mea culpa.
> It just seems like poor design to me, and it's given me trouble so many times without once actually providing me a benefit. So it's a reason. YMMV.
It's definitely a valid personal preference. When you say using const has given you trouble many times, do you have any particularly poignant example in mind?
OK, well, I was merely saying you need a citation for the situation we were discussing. I still stand by it.
> I think the MSVC devs classify it as a codegen bug since the cause is a logic error in the optimizer.
I'm gonna pull your own type of argument here, which is that they only consider it a bug because they have their own stricter guidelines for what they expect, not because it's actually a general language implementation bug. Definitely not something I'd call an "outright compiler bug" when the code is behaving sanely.
> When you say using const has given you trouble many times, do you have any particularly poignant example in mind?
I don't have a particularly poignant one at the top of my head right now, but I can give you a hypothetical one to illustrate the idea. Look at std::binary_negate (for our purposes assume the functor is required to be const-callable). People put const on the instance field of that sort of thing because, well, everything that can be const should be const dammit! Except now it gives you hell trying to assign to the object. That's the issue.
Ff a function takes a struct (or class) as argument can calls otherfunction(foo.bar), then the constness of foo's bar field matters. The same might apply to fields of this.
You can declare the function using int a(int b) in the header and then define it via int a(const int b).
struct { const int x; } y = { 1 };https://connect.microsoft.com/VisualStudio/feedback/details/...
IMO `const` should be used liberally: members, locals and other declarations.
When you're on a team and you have a data structure that has const members, it should give that newer/unfamiliar team member pause when they get the compilation error because they added a method that modifies the `const` member. Now they have an opportunity to take a step back and ask "Oh, why was it designed this way? What other assumptions in the code are invalidated if I need to remove the `const`?"
`const` for locals is good for those notorious ten-line functions that over time multiply into a 150-line function. Yes, we should refactor that mega function into something easier to digest. But right now I am trying to figure out this bug: I can see that ^^ up there 'foo' was initialized as a particular value, and down here it looks like it must have changed. Instead of looking through all of the hundred lines of code to see who might've updated 'foo', I know right away that a likely explanation is stack corruption.
This is BTW why I love that rust has opt-in mutability. It feels almost a little silly sprinking `const` thither and yon when it's only a few select places that it's actually un-needed.
Marking globals as const can move them to the read-only segment which has some modest performance improvements, but in most other cases const doesn't affect code-gen at all. Using const prevents programmers from doing certain things, and the compiler enforces that. That suggests that the compiler already knows whether or not programmers are doing those things - it doesn't need a 'const' hint to tell it. And in those cases where it can't tell, the 'const' hint is usually not sufficient for it to depend on.
In short, with the exception of moving globals to the read-only segment I am not aware of any performance improvements from using const.
Check out this subthread: https://news.ycombinator.com/item?id=13356101