Take note of the following C++ code:
#include <iostream>
using std::cout;
int foo (const int);
int main ()
{
cout << foo(3);
}
int foo (int a)
{
a++;
return a;
}
Notice that the prototype of foo()
takes a const int
and that the definition takes an int
. This compile without any errors...
Why are there no compilation errors?
Top-level
const
(i.e., that applies to the value that's passed, not something to which it points or refers) affects only the implementation, not the interface, of a function. The compiler ignores it from the interface viewpoint (i.e., the calling side) and enforces it only on the implementation (i.e., code in the body of the function).That'll throw an error during compiling.
Because it doesn't matter to the caller of the
foo
function whetherfoo
modifies its copy of the variable or not.Specifically in the C++03 standard, the following 2 snippets explain exactly why:
C++03 Section: 13.2-1
C++03 Section: 13.1-3
As others have explained, the Standard says it's ok, and that the compiler can afford to be lenient about enforcing this because it doesn't affect the caller, but nobody's answered why the compiler should choose to be lenient. It's not particularly lenient in general, and a programmer who's just been looking at the interface then dives into the implementation may have it in the back of their mind that a parameter is const when it's not or vice versa - not a good thing.
This leniency allows implementation changes without modifying headers, which using traditional make tools triggers recompilation of client code. This can be a serious issue in enterprise scale development, where a non-substantive change in a low-level header (e.g. logging) can force rebuilding of virtually all objects between it and the applications... wasting thousands of hours of CPU time and delaying everyone and everything waiting on the builds.
So, it's ugly, but a practical concession.
I've also answered another similar question which looks at why overloading of f(const T) and f(T) isn't allowed - may be of interest to anyone reading this - Top-level const doesn't influence a function signature