Note that the following two functions have the same type and signature:
void foo1(int t) {} // foo1 has type 'void(*)(int)', and signature '(*)(int)'
void foo2(const int t) {} // Also type 'void(*)(int)', signature '(*)(int)'
(the const
is not part of the function type or function signature). Similarly, a modifier (const
or volatile
) on the return type does not influence the function type or function signature.
However, in the function definition itself (not shown), the named variable t
does maintain the const
qualification in foo2
.
There are many StackOverflow questions discussing why the return type of the function is not considered as part of the function signature (used for overload resolution).
However, I cannot find any StackOverflow question that asks why argument modifiers (const
or volatile
) are not part of the function's type or signature. Also, I have looked directly in the C++11 standards document and find it difficult to unravel.
What is the rationale behind the fact that argument modifiers (i.e., const
and volatile
) are not part of a function's type or signature?
ADDENDUM For clarity, from R.MartinhoFernandes's answer below, I should clarify that in C++ (I think) the argument modifiers const
and volatile
are only ignored as part of the function type/signature if they are top-level modifiers - see that answer below.
const is pointless when the argument is passed by value since you will not be modifying the caller's object. Wrong. It's about self-documenting your code and your assumptions. If your code has many people working on it and your functions are non-trivial then you should mark const any and everything that you can.
C++ Reference. Programming Terms. Function Signatures. A function signature consists of the function prototype. What it tells you is the general information about a function, its name, parameters, what scope it is in, and other miscellaneous information.
A constant argument is the one whose modification cannot take place by the function. Furthermore, in order to make an argument constant to a function, the use of a keyword const can take place like- int sum (const int a, const int b).
What is the rationale behind the fact that argument modifiers (i.e., const and volatile) are not part of a function's type or signature?
From a caller's perspective, there is no difference between void foo(int)
and void foo(int const)
. Whatever you pass to it will not be modified, regardless of the modifier: the function will get a copy.
From an implementer's perspective the sole difference is that with void foo(int x)
you can mutate x
(i.e. your local copy) in the body, but you cannot mutate x
with void foo(int const x)
.
C++ acknowledges these two perspectives. The caller's perspective is acknowledged by making the two declarations void foo(int);
and void foo(int const);
declare the same function. The implementer's perspective is acknowledged by allowing you to declare a function as void foo(int x);
but define it as void foo(int const x) { /*...*/ }
if you want to make sure you don't accidentally assign to the argument.
Note that this only applies for top-level const
, i.e. const
that applies to the whole type. In things like int const&
or int const*
the modifier only applies to a part of the type, as "pointer to (const (int))", so it is not top-level const
. In int *const
however, the const
again applies to the whole type as in "const (pointer to (int))".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With