int fputc(int c, FILE *stream);
int fputs(const char *s, FILE *stream);
Why isn't const int c
required in fputc()'s declaration?
int fputc(int c, FILE *stream);
int fputs(const char *s, FILE *stream);
Why isn't const int c
required in fputc()'s declaration?
There's no point in marking parameters as const
in a function declaration. Arguments are passed by value, so the parameter is a copy anyway. It doesn't affect how the function can be called.
However, const char *s
does not mean s
is const
. What this declaration means is that s
is a pointer to a const char
; i.e. the fputs
function promises not to write through the pointer it is given. Also, there is an implicit conversion from char *
to const char *
(but not vice versa), meaning that fputs
can be called with both read-only and writeable strings.
The const
modifier prevents the function from changing the input parameter.
fputc
function uses int c
as input which is a value type. Because parameters are passed by value, the function can only change the internal copy, it could not change the original value.
fputs
function uses char *s
as input which is a pointer type, so the pointed memory could be changed by the function. The const
modifier protects the pointed memory by preventing the function from changing it.
Note 1: The const
modifier in function fputs
is on the char
type (const char *s
), which means the pointed memory cannot be changed. If the const
was on the input parameter s
(char * const s
), it would not protect the pointed memory, it would only protect the pointer itself which is anyway passed by value.
Note 2: As mentioned by Eric Postpischil in the comment and shown in Vlad from Moscow's answer, if the const modifier is in the functions declaration and not in the functions definition, it has no effect.
There is no need to make the first parameter const
; the "top level" of arguments are copied, not referenced, so all const
would do is prevent the called function from modifying its own copy of the argument.
Similarly, note that only the values being pointed to are const
for fputs
; the parameter isn't const char *const s
because the extra const-ness would only limit the callee's ability to modify where its copy of the pointer points to; the const
guarantee is only applied to the (shared) values being pointed to.
const char *s
doesn't mean that s
must point to a constant. It means that fputs
is not allowed to modify what is pointed to by s
.
When the compiler determines a function type then high level qualifiers of parameters are discarded.
So these two function declarations
int fputc(int c, FILE *stream);
int fputc( const int c, FILE *stream);
declare the same one function.
And these two function declarations
int fputs(const char *s, FILE *stream);
int fputs(const char * const s, FILE *stream);
also declare the same one function.
So the high-level qualifier const has a meaning not for the user of the function but only for the internal definition of the function. In any case a corresponding argument is passed by value that is the function deals with a copy of the argument. So whether inside the function the copy will have the qualifier const or will not does not matter for the user of the function.
Consider the following demonstrative program
#include <stdio.h>
void f( const int x );
void f( int x )
{
x += 10;
printf( "Inside the function x = %d\n", x );
}
int main( void )
{
int x = 1;
printf( "Before calling f x = %d\n", x );
f( x );
printf( "After calling f x = %d\n", x );
}
Its output is
Before calling f x = 1
Inside the function x = 11
After calling f x = 1
So it does not matter for the user of the function whether the parameter x of the function has the qualifier const. The both declarations declare the same one function from the point of view of the compiler (and the user of the function).
Function parameters are their local variables. And users do not bother whether or not some local variables will be declared within the function with the qualifier const.
Pat attention to that in this declaration
int fputs(const char *s, FILE *stream);
it is not the first parameter that is declared as constant. It is data pointed by the pointer that is constant.
But in this declaration
int fputc( const int c, FILE *stream);
the parameter itself that is constant.