2

Consider the following function declaration:

void foo(const int);

This function has the signature void(int). It can be defined as follows:

void foo(int) {}

This makes sense since whether or not the parameter is const within the function body doesn't matter to the caller. But then, why are we even allowed to write const parameters in a function declaration?

EDIT: This is not a duplicate of this question. In that question, const was added to a parameter in a function definition. They didn't discuss const parameters in a function declaration.

haslersn
  • 515
  • 5
  • 10
  • 5
    Making an additional rule to explicitly forbid it does not bring any benefit. – yuri kilochek Jun 11 '17 at 11:05
  • I think it is like the same as defining variables? –  Jun 11 '17 at 11:05
  • 1
    @Creep4Play But declaration is the same as **definition**, except that this definition doesn't define body... A definition can be re-defined. –  Jun 11 '17 at 11:10
  • No. There's no declaration, it's just a way of naming such definitions. And I know how to distinguish –  Jun 11 '17 at 11:11
  • 1
    @Matheus that's like saying a wheel is the same as a car, except it doesnt have the rest of the car... – M.M Jun 11 '17 at 11:12
  • @yurikilochek This way, there's an additional rule that says the `const` is ignored. So there's an additional rule either way. – haslersn Jun 11 '17 at 11:13
  • 1
    I'm not quite sure what kind of answer you would expect... there are basically two things I can imagine: (1) the part of C++ standard that defines what is allowed (2) the rationale behind writing the standard the way it is. – grek40 Jun 11 '17 at 11:14
  • @grek40 Or (3) there's a use for this I'm not aware of. – haslersn Jun 11 '17 at 11:21
  • 1
    Because it saves me an edit to parameters I want to be const in a function definition. I like to type my function declarations and then copy/paste to use for implementation (protect me from typos). If I am not going to change a parameter I like to declare it as const (const correctness). – Richard Critten Jun 11 '17 at 11:22
  • 1
    @Creep4Play use doesn't actually matter... either it's standard or not. If it is standard you might be lucky enough that the rationale behind making it standard is a use case. But nothing works just because it would be useful, it's always a matter of standard definition and implementation. – grek40 Jun 11 '17 at 11:30
  • @Galik By adding `const` at the function definition. See the linked question. – haslersn Jun 11 '17 at 11:44

2 Answers2

7

As far as the C++ language is concerned, these two declarations are precisely equivalent:

void foo(const int);
void foo(int);

Quoth the C++11 (latest public draft) standard, section 13.1 "Overloadable declarations":

Parameter declarations that differ only in the presence or absence of const and/or volatile are equivalent. That is, the const and volatile type-specifiers for each parameter type are ignored when determining which function is being declared, defined, or called. Example:

typedef const int cInt;
int f (int);
int f (const int);                // redeclaration of f(int)
int f (int)  { /* ...  */ }       // definition of f(int)
int f (cInt) { /* ...  */ }       // error: redefinition of f(int)

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.124 In particular, for any type T, “pointer to T,” “pointer to const T,” and “pointer to volatile T” are considered distinct parameter types, as are “reference to T,” “reference to const T,” and “reference to volatile T.”


124 When a parameter type includes a function type, such as in the case of a parameter type that is a pointer to function, the const and volatile type-specifiers at the outermost level of the parameter type specifications for the inner function type are also ignored.

So, the reason why function declarations are allowed to have const parameters is because the standard says they are equivalent to function declarations that have non-const parameters.

It should go without saying that the implication is you can't overload a function based on the cv-qualification of its parameters.

A const type specifier only matters in the function's definition, where it prevents the local modification of that parameter.

I suppose no one could think of a good reason to introduce the additional complexity that would be required to forbid const (and volatile) in declarations, when they are allowed and significant in definitions.

Community
  • 1
  • 1
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
0

This makes sense since whether or not the parameter is const within the function body doesn't matter to the caller. But then, why are we even allowed to write const parameters in a function declaration?

Because a declaration also introduces a definition, and const is useful in a definition. It prevents accidental modification of the object. (You should use const "by default", i.e. until you have to not.) The rules for a declaration, whether it introduces a definition or not, are pretty broadly stated in order to keep the language simple.

Could the standard have made it ill-formed to write const on a by-value parameter in a non-defining declaration? Well, sure. But it would have been extremely confusing, require more standardese, and (as you point out) wouldn't make the slightest bit of difference to anything important.

In short, why go out of your way to ban something for no good reason?

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055