Alerty
Alerty

Reputation: 5945

Why does a function declaration with a const argument allow calling of a function with a non-const argument?

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?

Upvotes: 15

Views: 2613

Answers (4)

Tony Delroy
Tony Delroy

Reputation: 106196

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

Upvotes: 2

Brian R. Bondy
Brian R. Bondy

Reputation: 347416

Because it doesn't matter to the caller of the foo function whether foo 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

Two function declarations of the same name refer to the same function if they are in the same scope and have equivalent parameter declarations (13.1).

C++03 Section: 13.1-3

Parameter declarations that differ only in the presence or absence of const and/or volatile are equivalent. Only the const and volatile type-specifiers at the outermost level of the parameter type specification are ignored in this fashion; const and volatile type-specifiers buried within a parameter type specification are significant and can be used to distinguish overloaded function declarations.

Upvotes: 35

Jerry Coffin
Jerry Coffin

Reputation: 490348

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).

Upvotes: 13

Esselans
Esselans

Reputation: 1546

int foo (const int a)
{
   a++;
   return a;
}

That'll throw an error during compiling.

Upvotes: -3

Related Questions