Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #164637

Re: What's wrong with "char op[8]=(istest?"ef":"df");"

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>

Show all headers | View raw


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 | NextPrevious in thread | Next in thread | Find similar | Unroll thread


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