In C, the prototype for the absolute value function (that accepts a float) is
float fabsf( float );
Why doesn't this prototype accept a constant value, like this:
float fabsf( float const );
fabsf won't change the value of the input, will it?
If I have a function that accepts an input and calls fabsf, am I forced to avoid specifying the input as const?
What is the appropriate way to handle const correctness in this situation?
C uses pass by value. The value for the parameter of a function is a copy of the argument you give.
It is OK to copy both const and non-const floats, and the result is a non-const float.
It is similar to assignment:
const float f = 5.5f; float g = f; // OK
In fact, the language specifies that the value of an expression can never be const
, i.e. when a value is read from a variable, that value is not const
even if the variable was.
Edit
As M.M commented, on parameters in prototypes the const
is ignored. The edited source of the original answer (see below) shows this:
float correct(float const value); float erroneous(float const value); float changer(float value); float correct(float value) { return -value; } float erroneous(float value) { value = -value; return value; } float changer(float value) { value = -value; return value; }
There is no error message.
Anyway, I'll leave the original in place in the hope it might help.
Original
The const
at a parameter makes this parameter read-only inside the function.
For example:
float correct(float const value) { return -value; } float erroneous(float const value) { value = -value; return value; } float changer(float value) { value = -value; return value; }
This source will not compile without error message.
The function correct()
will read the given value, change its sign, and return the negated value.
The function erroneous()
seems to do effectively the same, except that there is an assignment to the parameter. But as the parameter is const
this is not allowed.
Next, the function changer()
will work as the both before, but it gives no errors.
Let's look at the call site:
float f = 3.14159; float g = correct(f); // or erroneous(f) or changer(f)
The variable f
given as an argument will be copied into the parameter value
. It will never change even if changer()
will be called.
You might like to look at parameters as some kind of local variables. Actually they are mostly handled like this in the generated machine code.
So, why do you see const
sometimes? You see it if a pointer is defined as parameter.
When you don't want the value pointed to to be changed, you need to add const
; but do it at the correct position!
void effective(int const * pointer); void futile(int * const pointer); void possible_but_overly_restricted(int const * const pointer);
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