Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function args declared as consts became non constant with definition [duplicate]

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.

like image 522
Sitesh Avatar asked Feb 01 '18 08:02

Sitesh


2 Answers

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.

like image 154
Edgar Rokjān Avatar answered Oct 31 '22 22:10

Edgar Rokjān


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.

like image 45
R Sahu Avatar answered Oct 31 '22 21:10

R Sahu