Reputation: 1075
In C, why is it that I'm able to pass character arrays to functions that take a char *
as an argument, but I cannot pass the address of an array to functions that take a char **
?
UPDATE: Interestingly, changing the argument type to char* qux[12]
doesn't change the compiler warning at all
For example:
#include <stdio.h>
void foo(char* qux) { puts(qux); }
void bar(char** qux) { puts(*qux); }
void baz(char* qux[12]) { puts(*qux); }
int main() {
char str[12] = "Hello there";
foo(str);
bar(&str); // Compiler warning
baz(&str); // Same compiler warning
return 0;
}
In the second case, I get a compiler warning:
warning: incompatible pointer types passing 'char (*)[12]' to
parameter of type 'char **' [-Wincompatible-pointer-types]
What's going on here?
Upvotes: 4
Views: 3051
Reputation: 1556
In C, char *
represents a pointer to a contiguous sequence of characters. A contiguous sequence of characters with a null termination is what we call a string in C.
char **
is a pointer to a contiguous sequence of strings, and since each string is a contiguous sequence of characters terminated by a null ('\0') character, char **
represents a contiguous sequence to a contiguous sequence of null terminated characters.
Your declaration:
char str[12] = "Hello there";
Declares str
to be an array of characters of length 12, and it is initialized to the 12 characters {'H','e','l','l','o',' ','t','h','e','r','e','\0'}
. This is compatible with the parameter in foo(), but not with bar
and baz
both of which expect a contiguous sequence of pointers to strings. That is why those two give you a compiler warning because the parameter is incompatible with the arguments passed in.
Upvotes: 2
Reputation: 409442
Arrays naturally decays to pointers to their first element. So in the call foo(str)
it's really the same as foo(&str[0])
. This is of type char *
so it's all okay.
Now the second call, the one to bar
, is a different matter. When you use &str
you don't get a pointer to the arrays first element, you get a pointer to the array itself. And as the compiler noted, this is of type char (*)[12]
, which is very different from (and incompatible with) char **
.
Lastly, when you declare baz
you say that the argument is of type char *[12]
, that is you have an array or 12 pointers to char, not that you have a pointer to an array of 12 char
. Furthermore, due to the array decay to pointer thing, char *[12]
is actually the same as char **
.
Upvotes: 5