Some example code:
#include <stdio.h>
void func0(char *x)
{
printf("func0, %s, %zu\n", x, sizeof(x));
}
//for comparison with func0
void func1(char **x)
{
printf("func1, %s, %zu\n", *x, sizeof(*x));
}
int main()
{
char x[10] = "hello";
printf("%s, %zu, %zu, %zu\n", x, sizeof(x), sizeof(*x), sizeof("hello"));
func0(x);
func1(&x);
return 0;
}
For func1() (for comparison with func0), there is a "warning: incompatible pointer types passing 'char (*)[10]' to parameter of type 'char **'" and "Segmentation fault" error.
But for func0(), isn't the type 'char [10]' converted to 'char *'? If so, how is printf("%s") still able to print out "hello"? As shown in the output of func0():
hello, 10, 1, 6
func0, hello, 8
Is the information of length (i.e. N of char[N]) passed to func0?
What is the difference between x in func0 and *x in func1? Aren't they both an address pointing to a char?
Thank you very much.
[EDIT] Thank you so much for the detailed answers!
Let me summarise the warning and error for func1().
char x[10] = "hello";
The type of &x is char (*)[10], which is a pointer to an array, not pointer to pointer (e.g. char **). Hence the warning.
x is already the address (pointing to the string), and you can only take the address of an actual memory space. &x is not the address of x. **x in func1(): trying to read from an illegal address (the value of "H" in this example?), hence the Segmentation fault.
The extra question is:
What is the use case for using &x (e.g. char (*) [N])?
I see the difference between x and &x, char * / char[N] vs. char (*) [N], but I cannot figure out a case when you have to use char( *) [N]. x and &x are the same address after all.