Having troubles understanding types in C. What is the difference between const char *args[]
and char *const *args
?

- 19
- 6
-
Does this answer your question? [What is the difference between char \* const and const char \*?](https://stackoverflow.com/questions/890535/what-is-the-difference-between-char-const-and-const-char) – user10191234 Sep 18 '20 at 10:35
-
1Are you asking about the difference in `const` positioning, or the difference of `[]` vs. `*`? – interjay Sep 18 '20 at 10:39
2 Answers
When used as a function parameter char*const X[]
is exactly equivalent to char*const *X
.
Try compiling (https://gcc.godbolt.org/z/oxKMxs):
void a(char*const X[]);
void a(char*const *X);
//no conflicting-declaration error
C adjusts function-typed and array-typed parameters to pointers to the target.
The array-parameter syntax is a carry-over from B (C's predecessor langauges) which is frequently used to emphasize, to the reader, that a pointer to the first element of an array is expected, rather than just a pointer to a single element. But that's just a convention that's not at all enforced by compilers.
(When used outside of parameters, the two declarations are different—the second one denotes a real pointer, whereas the first denotes an array of an incomplete type. Such an incomplete array declaration is sometimes used for extern
references global arrays, where you frequently don't need the size (if you just need it to decay to a pointer), and if the size is needed (e.g., for sizeof
), then it can be supplied by a subsequent full declaration (e.g., char const*X[42];
), which will complete the first, incomplete one.)

- 58,047
- 6
- 95
- 142
Looking at how the function is defined
int execv(const char *path, char *const argv[]);
Then const char *path
means "the function will not change the data pointed at by path
, that's easy enough to understand, plain const correctness.
In the case of char *const argv[]
it means "the function will not mess around with your argv list and set its contents to point somewhere else". This parameter is meant to be an array of strings passed to the new process. Had the parameter been written as char* argv[]
then the function could in theory mess around with the individual pointer addresses to each string.
As for the difference between const char *args[]
and char *const *args
inside a parameter list, there is none. The former will implicitly "decay" into the latter and point at the first item in the array. Just like int a[n]
will decay into int* a
when declared as parameter. And this is the reason why we don't have to type out the array size but can leave it as []
- it won't matter since it will turn into a pointer anyhow.

- 195,001
- 40
- 254
- 396