Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #164637
| From | John Forkosh <forkosh@panix.com> |
|---|---|
| Newsgroups | comp.lang.c |
| Subject | Re: What's wrong with "char op[8]=(istest?"ef":"df");" |
| Date | 2022-01-26 08:18 +0000 |
| Organization | PANIX Public Access Internet and UNIX, NYC |
| Message-ID | <ssr049$8ao$1@reader1.panix.com> (permalink) |
| References | <ssos8v$pq3$1@reader1.panix.com> <ssp79k$lna$1@dont-email.me> |
James Kuyper <jameskuyper@alumni.caltech.edu> wrote:
> On 1/25/22 08:00, John Forkosh wrote:
>> Minimal working (or should I say non-working example)...
>>
>> #include <stdio.h>
>> int main () {
>> int istest=1;
>> char op[8] = (istest?"ef":"df");
>> /*char op[8] = "ef";*/
>> printf("op=%s\n",op); }
>>
>> for which cc emits the error...
>>
>> test.c: In function 'main':
>> test.c:4:16: error: invalid initializer
>> 4 | char op[8] = (istest?"ef":"df");
>> | ^
>>
>> But if I comment out that line and uncomment the one below it,
>> then it compiles and runs fine. ...
>
> The line that was commented line works because of the following clause
> from the standard:
>
> "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." (6.7.9p14).
>
> The line you actually used doesn't initialize the array with a string
> literal, but with the result of a conditional expression. That
> conditional expression has string literals as operands, but the
> initializer is not, itself, a string literal.
>
> "Except when it is the operand of the sizeof operator, or the unary &
> operator, or is a string literal used to initialize an array, an
> expression that has type "array of type" is converted to an expression
> with type "pointer to type" that points to the initial element of the
> array object and is not an lvalue." (6.3.2.1p4).
>
> "ef" and "df" are expressions of array type, so the above conversion
> applies. The exception for "a string literal used to initialize an
> array" does NOT apply, because it's the conditional expression's value
> that is being used to initialize the array, not the string literals.
>
> Therefore, both the second and third operands of the conditional
> expression are pointers to char, and therefore so is the result of that
> expression. You cannot use a char* as an initializer for an array.
>
> One alternative that would work is
>
> const char* op = (istest ? "ef" : "df");
>
> But I had to add the 'const' qualifier because it's undefined behavior
> to write to those strings. If you need writable memory, another
> alternative would be:
>
> char ef_op[8] = "ef";
> char df_op[8] = "df";
> char *op = (istest ? ef_op : df_op);
>
> But if do you need writable memory, I think the best way to do this
> would be:
>
> char op[8];
> strcpy(op, istest ? "ef" : "df");
Thanks for the several working alternatives. As mentioned earlier,
strcpy()'s the one I already went with. But char ef[8]="ef",df[8]="df";
char *op=(istest?ef:df); is yet another one I hadn't thought of.
> The other failed example that you provided in a later message fails for
> exactly the same reason:
>
>> char op[8] = (char *)"ef";
>
> (char*)"ef" is a cast expression, not a string literal. "ef" is not
> being used to initialize op, but as an operand of the cast operator. As
> such, it get implicitly converted into a pointer to the first element of
> the array, and then redundantly converted to a char*, something that
> cannot be used to initialize an array.
Sure. As mentioned in followup to Bart, I only tried that to double-check
Bart's (and your above) explanation. I was already expecting it to fail
for exactly Bart's (and your) reason, which I hadn't been previously
aware of. And just wanted to explicitly see it for myself. Before this
thread, I'd have expected it to work (but had never written it that way,
`cause "why bother?").
>> ... I've used this construction
>> a million times without problems. But a-million-and-one seems
>> to somehow be a problem. What's wrong???
>
> I doubt that you've ever used precisely this construct before - all of
> the relevant aspects of C have remained unchanged since K&R C. Anything
> you actually did must have differed from this construct in some
> important way.
As previously noted, agreed. But I'd have (inaccurately) sworn I had.
And I tried grep ? *.c|grep : to find some cases, but the closest I
came was stuff like char *infile = (argc>1?argv[1]:"testfile.txt");
which legitimately assigns to *ptrs, as everybody mentioned.
Thanks again, James, and "everybody".
--
John Forkosh ( mailto: j@f.com where j=john and f=forkosh )
Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
What's wrong with "char op[8]=(istest?"ef":"df");" John Forkosh <forkosh@panix.com> - 2022-01-25 13:00 +0000
Re: What's wrong with "char op[8]=(istest?"ef":"df");" John Forkosh <forkosh@panix.com> - 2022-01-25 13:09 +0000
Re: What's wrong with "char op[8]=(istest?"ef":"df");" Bart <bc@freeuk.com> - 2022-01-25 14:03 +0000
Re: What's wrong with "char op[8]=(istest?"ef":"df");" John Forkosh <forkosh@panix.com> - 2022-01-25 14:33 +0000
Re: What's wrong with "char op[8]=(istest?"ef":"df");" Mateusz Viste <mateusz@xyz.invalid> - 2022-01-25 14:36 +0100
Re: What's wrong with "char op[8]=(istest?"ef":"df");" John Forkosh <forkosh@panix.com> - 2022-01-25 14:41 +0000
Re: What's wrong with "char op[8]=(istest?"ef":"df");" Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-01-25 06:39 -0800
Re: What's wrong with "char op[8]=(istest?"ef":"df");" John Forkosh <forkosh@panix.com> - 2022-01-25 14:56 +0000
Re: What's wrong with "char op[8]=(istest?"ef":"df");" James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-01-25 11:08 -0500
Re: What's wrong with "char op[8]=(istest?"ef":"df");" John Forkosh <forkosh@panix.com> - 2022-01-26 08:18 +0000
Re: What's wrong with "char op[8]=(istest?"ef":"df");" Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-01-25 14:37 -0800
Re: What's wrong with "char op[8]=(istest?"ef":"df");" John Forkosh <forkosh@panix.com> - 2022-01-26 08:27 +0000
Re: What's wrong with "char op[8]=(istest?"ef":"df");" Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-01-25 19:49 -0800
Re: What's wrong with "char op[8]=(istest?"ef":"df");" Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-01-25 19:56 -0800
Re: What's wrong with "char op[8]=(istest?"ef":"df");" James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-01-25 23:37 -0500
Re: What's wrong with "char op[8]=(istest?"ef":"df");" Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-01-25 20:54 -0800
Re: What's wrong with "char op[8]=(istest?"ef":"df");" John Forkosh <forkosh@panix.com> - 2022-01-26 08:37 +0000
Re: What's wrong with "char op[8]=(istest?"ef":"df");" Kaz Kylheku <480-992-1380@kylheku.com> - 2022-01-26 05:08 +0000
Re: What's wrong with "char op[8]=(istest?"ef":"df");" John Forkosh <forkosh@panix.com> - 2022-01-26 09:22 +0000
Re: What's wrong with "char op[8]=(istest?"ef":"df");" John Forkosh <forkosh@panix.com> - 2022-01-26 09:24 +0000
csiph-web