Is there any way that I can add const
keyword to an array passed as a parameter to function:
void foo(char arr_arg[])
If I place const
before char
(void foo(const char arr_arg[])
) or after char
(void foo(char const arr_arg[])
), that would mean than it's char
which is constant, not the arr_arg
.
I have just read that under the hood an array sent as a parameter to function is represented as a pointer, so void foo(char arr_arg[])
is the same as void foo(char* ptr_arg)
.
Taking it into account, I may rewrite the function as void foo(char * const ptr_arg)
for it to be exactly what I want to achieve.
But I want to know if there is a way to add const
keyword in this declaration void foo(char arr_arg[])
for it to be the same as void foo(char * const ptr_arg)
(and not void foo(char const * ptr_arg)
or void foo(const char * ptr_arg)
)?
I just want to understand if there is a syntax to make arr_arg
constant with array notation []
.
In C you have to put const
between the []
, however strange that might look to an unprepared person
void foo(char arr_arg[const]);
This is "new" C99-specific syntax. In C89/90 or C++ there no way to do it with "array" syntax, so you have to switch to the equivalent "pointer" syntax, as suggested in David's answer.
The first thing is that in your particular signature, the argument is transformed by the compiler into a pointer, so what you have is:
void foo( char * arg );
Now, there are two entities that can be made const in that signature: the pointer and the pointed type. To make the pointed type can be made const in two different yet equivalent ways [*]:
void foo( const char * arg );
void foo( char const * arg );
The pointer could be made const with the syntax:
void foo( char * const arg );
But note that in a function signature, in the same way that char arg[]
is transformed into a pointer char *arg
, the top level qualifier is discarded. So from the point of view of the declaration, these two are equivalent:
void foo( char * const arg );
void foo( char * arg );
In the definition, the top level const can be use to instruct the compiler that the argument pointer (by value) should not be changed within the function, and it will detect if you attempt to reset the pointer to a different location. But, if only the pointer is const, then the compiler will gladly let you modify the pointed memory. If you don't want the function to change the contents of the array, then you should opt for one of the first two signatures.
[*] I tend to prefer the char const *
format, as it provides a consistent way of reading types: from right to left it reads: a non-const pointer to a const char. Additionally it is simpler to reason about typedef-ed types (by performing direct substitution in the expression). Given typedef char* char_p;
, const char_p
and char_p const
are both equivalent to char * const
and different from const char *
. By consistently using const
on the right you can just blindly substitute the typedef and read the type without having to reason.
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