I noticed that it\'s possible to have const
qualifier on a value argument present in the function declaration and then omitted in the definition. That doesn\'t
This is a bug because it prevents legitimate code like:
/* API declaration */
void f(int);
/* Implementation */
void f(const int x) /* my business: x is my local var and I want it const */
{
}
I can't believe anyone would code out of their way to diagnose this as a problem.
Incidentally, GCC, which doesn't complain about this, used to have a warning about this situation. Perhaps it still does:
void f(int func_ptr(void));
void f(int (*func_ptr)(void))
{
}
This is purely a stylistic inconsistency that doesn't serve a purpose, though.
This behavior is defined by the standard and as far as I can tell gcc
is correct here, if we look at the draft C++ standard section 13.1
Overloadable declarations paragraph 3 says:
[...]-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.
and provides this example:
[ 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)
—end example ]
and some details clarifying that that this applies only to the outermost cv qualifiers (emphasis mine):
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.123 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.”
and as far as I can tell this applies to template functions in template classes as well from section 14.8
Function template specializations specifically 14.8.3
Overload resolution which says:
[...]The complete set of candidate functions includes all the synthesized declarations and all of the non-template overloaded functions of the same name. The synthesized declarations are treated like any other functions in the remainder of overload resolution, except as explicitly noted in 13.3.3.144