I know that it improves readability and makes the program less error-prone, but how much does it improve the performance?
And on a side note, what’s the major difference between a reference and a const pointer? I would assume they’re stored in the memory differently, but how so?
[Edit: OK so this question is more subtle than I thought at first.]
Declaring a pointer-to-const or reference-of-const never helps any compiler to optimize anything. (Although see the Update at the bottom of this answer.)
The
constdeclaration only indicates how an identifier will be used within the scope of its declaration; it does not say that the underlying object can not change.Example:
The compiler cannot assume that
*pis not modified by the call tobar(), becausepcould be (e.g.) a pointer to a global int andbar()might modify it.If the compiler knows enough about the caller of
foo()and the contents ofbar()that it can provebar()does not modify*p, then it can also perform that proof without the const declaration.But this is true in general. Because
constonly has an effect within the scope of the declaration, the compiler can already see how you are treating the pointer or reference within that scope; it already knows that you are not modifying the underlying object.So in short, all
constdoes in this context is prevent you from making mistakes. It does not tell the compiler anything it does not already know, and therefore it is irrelevant for optimization.What about functions that call
foo()? Like:Can the compiler prove that this prints 37, since
foo()takes aconst int *?No. Even though
foo()takes a pointer-to-const, it might cast the const-ness away and modify the int. (This is not undefined behavior.) Here again, the compiler cannot make any assumptions in general; and if it knows enough aboutfoo()to make such an optimization, it will know that even without theconst.The only time
constmight allow optimizations is cases like this:Here, to modify
xthrough any mechanism whatsoever (e.g., by taking a pointer to it and casting away theconst) is to invoke Undefined Behavior. So the compiler is free to assume you do not do that, and it can propagate the constant 37 into the printf(). This sort of optimization is legal for any object you declareconst. (In practice, a local variable to which you never take a reference will not benefit, because the compiler can already see whether you modify it within its scope.)To answer your “side note” question, (a) a const pointer is a pointer; and (b) a const pointer can equal NULL. You are correct that the internal representation (i.e. an address) is most likely the same.
[update]
As Christoph points out in the comments, my answer is incomplete because it does not mention
restrict.Section 6.7.3.1 (4) of the C99 standard says:
(Here B is a basic block over which P, a restrict-pointer-to-T, is in scope.)
So if a C function
foo()is declared like this:…then the compiler may assume that no modifications to
*poccur during the lifetime ofp— i.e., during the execution offoo()— because otherwise the Behavior would be Undefined.So in principle, combining
restrictwith a pointer-to-const could enable both of the optimizations that are dismissed above. Do any compilers actually implement such an optimization, I wonder? (GCC 4.5.2, at least, does not.)Note that
restrictonly exists in C, not C++ (not even C++0x), except as a compiler-specific extension.