5

Code

class A
{
 public:
    void f(const int i);
};
void A::f(int i)
{
    std::cout<<++i<<std::endl;
}
int main()
{
   A a;
   a.f(1);
}

Why compiler does not give an error in this case ? Why the definition overrides the constant argument ? Also, when the argument is of type reference (&) the compiler throws error but why not in this case ?

Is there any compiler flag to enable warning on these mentioned cases ?

I am interested more from compiler error POV. Because one can easily put declaration (const) and definition(non-constant) differently and still compiler accepts it. If a mistake can be made it will eventually be made. Why can't compiler complain when there is such difference present.

Sitesh
  • 1,816
  • 1
  • 18
  • 25

2 Answers2

5

From 11.3.5 Functions [dcl.fct]:

  1. A single name can be used for several different functions in a single scope; this is function overloading (Clause 16). All declarations for a function shall agree exactly in both the return type and the parameter-typelist. The type of a function is determined using the following rules. The type of each parameter (including function parameter packs) is determined from its own decl-specifier-seq and declarator. After determining the type of each parameter, any parameter of type “array of T” or of function type T is adjusted to be “pointer to T”. After producing the list of parameter types, any top-level cv-qualifiers modifying a parameter type are deleted when forming the function type. The resulting list of transformed parameter types and the presence or absence of the ellipsis or a function parameter pack is the function’s parameter-type-list.

Basically, it means, that const int and int are interchangeable in the context of your question.

On the other hand, if you add a reference, like const int&, const is not a top level cv-qualifier anymore (it marks the referenced value as const), so the compiler complains.

Usually, const is added to the definition in order to emphasise that the parameter is not changed inside the function body.

Edgar Rokjān
  • 17,245
  • 4
  • 40
  • 67
  • Emphasize and, more importantly, enforce. – Quentin Feb 01 '18 at 09:37
  • I am interested more from compiler error POV. Because one can easily put declaration (const) and definition(non-constant) differently and still compiler accepts it. If a mistake can be made it will eventually be made. Why can't compiler complain when there is such difference present. – Sitesh Feb 01 '18 at 12:40
3

The function declaration

void f(const T arg);

is same as

void f(T arg);

However,

void f(const T& arg);

is not the same as

void f(T& arg);

and

void f(const T* arg);

is not the same as

void f(T* arg);

void f(const T arg);
void f(T arg);

are same because top-level cv-qualifiers are removed for function resolution purposes. There, the const-ness is applied to the top-level type, T.

OTOH,

void f(const T& arg);
void f(T& arg);

are not same since the const-ness is applied to the object being referred to by the reference arg, not to arg itself which is just a top-level thing.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • 2
    Mention *top-level* const-ness to explain it. Not all const-ness are same in C++. – Nawaz Feb 01 '18 at 08:45
  • @Nawaz, I don't follow your drift. How would top-level const-ness affect the answer? – R Sahu Feb 01 '18 at 08:48
  • `const T arg` and `T arg` are equivalent because `const T arg` has top-level const, while `const T * arg` has not, though `T * const` is equivalent to `T *`, again because `T * const` has top-level const, hence can be ignored in the definition. – Nawaz Feb 01 '18 at 08:50
  • `void f(const T arg);` is not the "same" that `void f(T arg);` ! – Stargateur Feb 01 '18 at 08:54
  • 2
    @Stargateur: As long as `T` is a value type, it *is* the same in this context. The `const` tells the *caller* that his argument won't be changed by `f()`. As the parameter is passed by value anyway, the contract indicated by the `f( const T arg )` declaration is honored even by `f( T arg )` for value types. Check Edgar's answer (or the linked dupe) for the standard legalese. – DevSolar Feb 01 '18 at 08:59
  • 1
    @RSahu: Have edited your post. Feel free to rollback if it's not good enough. – Nawaz Feb 01 '18 at 09:07
  • @DevSolar it's the same in all cases of `T` – M.M Feb 01 '18 at 09:16
  • @Nawaz, not a problem. Thanks for the edit. – R Sahu Feb 02 '18 at 18:38