tags:

views:

339

answers:

6

I'm a const fiend, and I strive to make everything as const as possible.

I've tried looking at various dissassembly outputs from const and non const versions of functions, and I've yet to see a marked improvement however. I'm assuming compilers nowadays are able to do smart things with non const functions that could technically be const.

Are there still cases where const is useful at the machine level? Any examples?

+9  A: 

As far as I know, the only effect of marking a function const is to allow the function to be called on a const object. There's no optimization benefit.

Herb Sutter has an article which discusses const and optimization in depth:

The one area that const is useful at the machine level is when applied to data - const data might be able to be placed in non-writable memory.

Michael Burr
Do you know of any platforms/implementations that actually have this proverbial non-writable memory? And even if one does, how is that a performance optimization? Why would it be any faster to access?
I have found that `static const` for a variable is faster than `const`. The `const` version copied the data from ROM to stack whereas the `static const` version accessed the data directly from ROM. This was proven in the assembly listing.
Thomas Matthews
(+1) still shouldn't have used the non-writeable memory example :D
Hassan Syed
Embedded systems, like the one I'm working on now. In terms of speed, const data in ROM is likely to be slower than if the data were in RAM. However, often a more important consideration is that there's likely to be far less RAM than ROM, so even if it's slower the preference in general is to put it in ROM. Also even on desktop systems, const data might go into pages marked read-only - there's probably no performance benefit to it, just correctness (and possibly the fact that it never needs to go into the pagefile - but if that's a measurable difference, you must have a *ton* of const data).
Michael Burr
(just curious) you can tell your compiler which memory addresses hold const data ? Or is your compiler aware of the chips on board of your embedded platform ?
Hassan Syed
This kind of configuration is typically done with a file that describes the memory layout to the linker.
Michael Burr
very interesting indeed, do you have any links to any documentation ?
Hassan Syed
@Hassan: I'm using IAR tools right now, the ILINK linker docs are here (page 331): ftp://ftp.iar.se/WWWfiles/arm/Guides/odarm-4.pdf. You can also look at GNU's ld linker docs: http://sourceware.org/binutils/docs-2.20/ld/. They aren't the easiest reads and I'm not an expert on setting up an ilink or an ld config. In fact, the technique that seems to be used most often for setting up a new configuration is to take the script from a project that you think is pretty similar, and change the numbers in it to match the new target.
Michael Burr
+17  A: 

The primary use of const isn't to generate better code, but to protect you from yourself, ensuring that you don't accidentally change something you didn't mean to.

Jerry Coffin
+1: Definitely agree. But people do tout it as a possible compiler optimization. I'm curious if that still holds true, and what the cases are.
Eddie Parker
(-1) in a language that is a minefield to a programmer both new and old -- const doesn't add any safety -- it just makes everything more complicated. Now from a compiler optimization point of view .....
Hassan Syed
What? `const` doesn't add safety? Let's see, you can break something you can change, but you can't break something you can't change...
GMan
@Hassan: I wish I could down-vote a comment.
@gman are your favouring the most obvious explanation or the most practical one (--i.e., from experience of a few million lines of code ? )
Hassan Syed
@stingray you can downvote my answer -- for balance.
Hassan Syed
`const` can allow compiler optimizations. For example, `const` data in a for loop can be factored out or preserved by a more efficient means.
Thomas Matthews
I'm not sure I understand, Hassan. My argument is pretty straightforward. You can't break something if you can't logically touch it. Simple fact.
GMan
If you don't want something to change -- the bottom line is making that item opaque... either by hiding the declaration from the exported headers .... or by using a #define is far more effective (please don't start on #define's) =D the const keyword often gets lost in class hierarchies and even if not it can easily be clobered by a cast (even an innocent one). So, from my experience const as a modeling element leads to a false sense of security -- I still use it though -- but I think stating the obvious when there is a more powerful reason for the const keyword is unfaithful to the concept.
Hassan Syed
Not changing an item I need to look at isn't the same as removing it from my sight. `#define`'s are worse, and don't respect scope. This is C, not C++. You need to re-evaluate your understanding of the language and good code practices.
GMan
@gman you obviously did not read the `I still use it` part did you ?
Hassan Syed
@Hassan: C++ is a minefield, so we should *appreciate* things like `const` that make it less minefieldish :) It's a shame that C-style casts can remove constness -- compilers should warn at least. It's an excellent idea to remove all C-style casts from your code -- then violations of constness can be easily found with `grep const_cast *.c`.
j_random_hacker
Saying you still do something you preach against is not only hypocritical, it doesn't double as a get-out-free card. Your argument is the same regardless of your actions. Your actions contradict your argument, hence hypocritical, but don't neglect it.
GMan
+2  A: 

The purpose of const is primarily an architectural one. When you declare something as const you should actually be thinking on what it represents: something that cannot change.

Bruno Reis
Or, more correctly, something that *should* not change.
greyfade
Not necessarily "more correct". If you are writing a physics system, the speed of light *cannot* change, while, say, the pression inside a ball *should not* change. They are very different concepts.
Bruno Reis
But this is not physics, its C++. And as other answers point out, const member functions don't guarantee that you cannot change anything.
Georg Fritzsche
I think an important note to make is what we mean by change. Even with mutable members, if you don't *logically* change the class, the class is the same. That is, outside users would never know. Just semantics being disagreed upon, here, I think.
GMan
Guys, you don't get the most important idea: it's about MODELLING. If, in the domain your are modelling, some property should not / must not be changed, you SHOULD clearly state it in your code. In C++ you do this with "const". Were it Java, you would use "final". Were it C#, you would use "readonly", ... It's not about what you can/cannot do. You can always hack your OS and change whatever memory you want to. But this is irrelevant. The point is that your code should reflect as closely as possible the domain you are modeling. In some cases this has another benefit: code easier to optimize.
Bruno Reis
+1  A: 

This is not exactly a direct answer to the detailed version of your question, but it matches the title's question.

I like to use const pretty aggressively too, in part because I think there's a minute change it will improve performance, but mostly because it reduces errors and communicates intent better.

  1. Having const methods allows users the freedom of having useful const objects.
  2. Having const objects allows library writers to succinctly communicate to users whether a function or method can change the input parameters.
  3. Having const objects allows you to have the compiler yell at you if you accidentally do something that will modify and object you don't want to modify.
Mr Fooz
+1  A: 

I follow your strategy, and I see it's main usefulness as being to a human. I've adopted a very functional style in a lot of my programming, and const helps enforce that and illustrate that to other programmers who might be reading my code.

In truth, I see some of the new function attributes that C++0x is going to support as being a little more useful for compilers. Knowing that the result of a function depends solely on its arguments, and does not follow any pointers passed to it means that calls to the function can be subjected to CSE.

Omnifarious
+12  A: 

It's pretty rare for const to actually help the compiler optimize. You have to keep in mind that the const_cast can be used anywhere to remove constness from an object (although actually modifying the resulting object isn't always well-defined, it is in some cases, and so the compiler has to be careful about assuming that just because a const object is passed to a function, it won't be modified)

Likewise, the mutable keyword messes things up. You might pass a const object to a function, but what if that object contains a mutable field?

The compiler has to do a lot of work to verify that it's safe to assume that an object is really constant -- and by the time it's done all this verification, the const keyword doesn't really matter, because it could have done all the same analysis on a regular non-const object as well to determine that it isn't being modified and can be treated as constant.

I won't say there aren't a few border cases where the const keyword can enable new optimizations, but in general, const isn't a performance consideration, but a correctness one. Use it to catch more bugs at compile-time, not to speed up your code.

jalf
+1 for "by the time it's done all this verification, the const keyword doesn't really matter..." - that's the key. Also, nice summary in general.
Michael Burr
The thing I tell people is that `const` means "read-only access, please" more than it means "constant", because of things like `mutable`, and because `const` objects are not always located in read-only memory.
Mike DeSimone