C
lets me use char
pointers and arrays interchangeably often enough that I often think of them as completely interchangeable. But the following code demonstrates this is not true. Can anyone please explain why the initialization of const char d[]
with the ternary operator, in the code below, is illegal?
/* main.c */
#include <stdio.h>
int main()
{
const char* a = "lorem";
const char b[] = "ipsum";
int* p;
const char* c = ( *p ? "dolor" : "sit" );
const char d[] = ( *p ? "amet" : "consectetur" ); // Why am I an error?
return 0;
}
Compilation:
> gcc -g main.c
main.c: In function \u2018main\u2019:
main.c:10:20: error: invalid initializer
const char d[] = ( *p ? "amet" : "consectetur" ); // Why am I an error?
Related question: in case my terminology has been imprecise here: what is the correct term to describe const char d[]
? Is it an array? A variable-length array? Something else? It is not considered a pointer - true?
Edit: I believe this question is not answered by Array initialization with a ternary operator?
RE: the referenced question, I believe the premise is slightly different. E.g. the accepted answer explains that { 1, 2 };
(or { 'a', 'b' );
) are not valid C
expressions, which I know already and accept. However "amet";
and "consectetur";
are valid C
expressions.
6.7.9 Initialization
...
14 An array of character type may be initialized by a character string literal or UTF−8 string literal, optionally enclosed in braces. Successive bytes of the string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the elements of the array.
C 2011 Online Draft
( *p ? "amet" : "consectetur" )
is not a string literal, nor does it evaluate to a string literal. It evaluates to an expression of type char *
, which on its own is not a valid array initializer, and that evaluation does not occur until runtime.
Not to mention, p
is uninitialized, so the expression is undefined to begin with.
String literals are slightly magical. Ordinarily (when used in expressions), they represent arrays. Arrays can "decay" (implicitly convert) to pointers, which is why e.g.
const char *p = "foo";
is valid. "foo"
is a normal expression here. You could also write
const char *p;
p = "foo"; // assignment, not initialization
However, if a string literal is used to initialize an array, it behaves like an initializer list of characters:
char s[] = "foo";
// equivalent to:
char s[] = { 'f', 'o', 'o', '\0' };
In your example of
const char d[] = ( *p ? "amet" : "consectetur" );
the initializer is not a sole string literal; it is an expression. Hence both string literals decay to pointers, and then you get an error because you cannot initialize an array from a pointer. (In fact, you cannot initialize an array from an expression at all.)
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