Isn't the address of an array and thus of all its elements as well constant anyway?
And if so, in a declaration like:
char *const argv[]
isn't the const
qualifier redundant?
No, the const
in char *const argv[]
is not redundant.
First, const
and "constant" are actually two different things in C, even though the const
keyword is obviously derived from the word "constant". A constant expression is one that can be evaluated at compile time. const
really means "read-only". For example:
const int r = rand();
is perfectly legal.
Yes, the address of an array -- like the address of any object -- is read-only. But that doesn't mean that the value of the array (which consists of the values of its elements) is read-only, any more than any other object is necessarily read-only.
Consider these three declarations:
char *arr1[10];
char *const arr2[10];
const char *arr3[10];
arr1
is a 10-element array of pointers to char
. You can modify the char*
elements and you can modify the objects that those elements point to.
arr2
is an array of const
(read-only) pointers to char
. That means that you can't modify the char*
elements of the array (once they're initialized) -- but you can still modify the char
objects or arrays that those elements point to.
And arr3
is an array of pointers to const char
; you can modify the array elements, but you can't modify what they point to.
Now the fact that you used the name argv
suggests that you're talking about the second parameter to main
, which has some huge effects on this. The language specifies that main
's second parameter is
char *argv[]
or, equivalently,
char **argv
There is no const
. You can probably get away with adding one, but it's best to follow the form specified by the standard. (Update: I see from your comment that you're asking about the argv
parameter of getopt()
, which is defined as char * const argv[]
.)
And since it's a parameter defined as an array, another rule comes into play: a parameter defined as an array of some type is "adjusted" to a pointer to that type. (This rule applies only to parameters.) This isn't a run-time conversion. A function cannot have a parameter of array type.
The relationship between arrays and pointers in C can be confusing -- and there's a lot of misinformation out there. The most important thing to remember is that arrays are not pointers.
Section 6 of the comp.lang.c FAQ is an excellent explanation of the details.
Isn't the address of an array and thus of all its elements as well constant anyway?
Yes, and it is true for any object in C
. Recall that by object here, we mean a location in memory having a value and referenced by an identifier. The identifier is bound to a fixed memory location throughout its scope and you cannot change it. You can change the value of the object though.
int a = 4;
a = 6; // legal. you can change the value of the object
&a = 23456; // illegal. you cannot change the address of the object
Similarly, an array is also an object and each of its elements will have a fixed memory address. However, the value held by an element of the array has nothing to do with the address of the element.
Note that if the declaration appears in a function parameter list, then the following are equivalent
char *const argv[]
char *const *argv
which means that argv
is a pointer to an object which is of type char *const
, i.e., a constant pointer to a character. It's obvious that char *const *argv
and char **argv
are different. So let's take another example.
char *const argv[10];
The above statement defines argv
to be an array of 10
constant pointers to a character. This means that you have to initialize the array and cannot later change the pointers to point to a different character. However, this has nothing to do with the address of the array elements.
char c = 'A';
char d = 'B';
char *const argv[2] = {&c, &d};
argv = &c; // illegal. you cannot the change the address of an object
argv[0] = &d; // illegal. you cannot change the value of the array element
*argv[0] = 'C'; // legal. you change the value pointed to by the element
Without the const
qualifier, char *argv[2]
means an array of 2
pointers to characters.
This is clearly different from the case when we have the const
qualifier as explained above. Therefore, to answer your second question, no, the const
qualifier is not redundant. That's because the const
qualifier qualifies the type of the array elements.
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