Path: csiph.com!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: Tim Rentsch
Newsgroups: comp.lang.c
Subject: Re: What's wrong with "char op[8]=(istest?"ef":"df");"
Date: Tue, 25 Jan 2022 06:39:25 -0800
Organization: A noiseless patient Spider
Lines: 69
Message-ID: <86mtjjnale.fsf@linuxsc.com>
References:
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Injection-Info: reader02.eternal-september.org; posting-host="432f4a244a87599086cf3ea4841708e3"; logging-data="15240"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/rnxqsQZYUXYZ9CJJr8tglYHTJGrId6f8="
User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Cancel-Lock: sha1:C86R4o02BRiQWHNQKO4qTkHaeNk= sha1:a1GwGjJiEbMSbgbbKf+uEBi1WhM=
Xref: csiph.com comp.lang.c:164612
John Forkosh writes:
> Minimal working (or should I say non-working example)...
>
> #include
> 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. I've used this construction
> a million times without problems. But a-million-and-one seems
> to somehow be a problem. What's wrong???
What you've done is take a construct (the istest?"ef":"df"
subexpression) that works in lots of contexts, and then tried to
use it in a different context where it doesn't work.
The '=' in a declaration is not an assignment but rather is used
for initialization. Assignment and initialization are similar
in many ways but not in all ways.
For the declaration of 'op', what is being initialized is an
array. Initializers for arrays usually are written using a
brace-enclosed list of values, such as
char op[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
For arrays of character type, C also allows two special forms
char op[8] = "foo";
or
char op[8] = { "foo" };
The declaration of op[8] in your program doesn't use any of those
three forms, so the compiler complains.
To get what you want, you could write a rather cumbersome array
initializer:
char op[8] = { istest ? 'e' : 'd', 'f' };
Alternatively, you could declare op[8] without an initializer and
subsequently use a string function such as strcpy() to provide
values to array elements (which in some cases will be only some
of the array elements, but presumably you don't care about that
as long as there is a terminating null). This method is similar
to the code in your followup posting.
For this particular usage, strncpy() may be a better choice than
strcpy(), as for example
strncpy( op, istest?"ef":"df", sizeof op );
because it will initialize all the elements of the array, and
also is guaranteed not to write beyond the end of the array,
which could happen if strcpy() were used (depending of course
on what string is provided for the second argument).