I have a function, f(char **p)
, and I wanted to call it in the simplest way I could.
I tried
char ** p = {"a", "b"};
f(p);
and got:
scalar object requires one element in initializer
so I changed it into
char * p[2] = {"a", "b"};
f(p);
and that went fine [would have been also fine with just char * p[]
].
Why can't I create an array of pointers on the fly like the following?
f({"a", "b"});
This gives a warning:
char ** p = {"a", "b"};
because p
is not an array.
This is also not legal:
f({"a", "b"});
since curly braces by themselves are not allowed in an expression (but can be used as an initializer).
It is possible to create an array on the fly like that using a compound literal:
f((char *[]){"a", "b"});
You could also use a compound literal to initialize a temporary:
char ** p = (char *[]){"a", "b"};
Unlike the first statement, this is valid because the literal is an array of type char *[2]
and will decay to a char **
which can be used to initialize a variable of this type.
See section 6.5.2.5 of the C standard for more details on compound literals.
This declaration char ** p = {"a", "b"};
triggers a warning because C does not know how to interpret the content of {
}
braces:
char**
suggests it's a single pointer-to-pointer-to-char{
}
specifies two items.You need to tell C that you are initializing a pointer to pointer with a pointer to the initial element of an anonymous array by specifying a type in front of the braces:
char ** p = (char*[]){"a", "b"}
This construct is called a "compound literal". It could be used in a declaration, but it also works as an expression.
Note: if you are planning to pass an array like that to a function, you need to provide a way to determine the size of the array. One approach is to pass NULL
to "terminate" the array, like this:
void f(char **p) {
int i = 0;
while (*p) {
printf("%d:%s\n", i++, *p++);
}
}
int main(void) {
f((char*[]){"a", "b", NULL});
return 0;
}
Demo.
C99 and later added compound literals for the exact purpose: creating array and structs on the fly
Example:
struct foo {int a; char b[2];} structure;
structure = ((struct foo) {1, 'a', 0});
int *y = (int []) {1, 2, 3};
int *z = (int []) {1};
Apart from std C99 and later, GCC provide this feature as an extension too.
In you case this will work
f((char *[]){"a","b"});
(char *[]){"a","b"}
is a compound literal which creates an array of 2 pointers to char
on the fly.
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