Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  newsreader  groups  login

Message-ID:  

Staff meeting in the conference room in %d minutes.


devel / comp.lang.c / What's wrong with "char op[8]=(istest?"ef":"df");"

SubjectAuthor
* What's wrong with "char op[8]=(istest?"ef":"df");"John Forkosh
+* Re: What's wrong with "char op[8]=(istest?"ef":"df");"John Forkosh
|`* Re: What's wrong with "char op[8]=(istest?"ef":"df");"Bart
| `- Re: What's wrong with "char op[8]=(istest?"ef":"df");"John Forkosh
+* Re: What's wrong with "char op[8]=(istest?"ef":"df");"Mateusz Viste
|`- Re: What's wrong with "char op[8]=(istest?"ef":"df");"John Forkosh
+* Re: What's wrong with "char op[8]=(istest?"ef":"df");"Tim Rentsch
|`- Re: What's wrong with "char op[8]=(istest?"ef":"df");"John Forkosh
+* Re: What's wrong with "char op[8]=(istest?"ef":"df");"James Kuyper
|`- Re: What's wrong with "char op[8]=(istest?"ef":"df");"John Forkosh
+* Re: What's wrong with "char op[8]=(istest?"ef":"df");"Stefan Ram
|`- Re: What's wrong with "char op[8]=(istest?"ef":"df");"John Forkosh
+* Re: What's wrong with "char op[8]=(istest?"ef":"df");"Keith Thompson
|`- Re: What's wrong with "char op[8]=(istest?"ef":"df");"John Forkosh
+* Re: What's wrong with "char op[8]=(istest?"ef":"df");"Andrey Tarasevich
|+- Re: What's wrong with "char op[8]=(istest?"ef":"df");"Keith Thompson
|+* Re: What's wrong with "char op[8]=(istest?"ef":"df");"James Kuyper
||`- Re: What's wrong with "char op[8]=(istest?"ef":"df");"Andrey Tarasevich
|`- Re: What's wrong with "char op[8]=(istest?"ef":"df");"John Forkosh
`* Re: What's wrong with "char op[8]=(istest?"ef":"df");"Kaz Kylheku
 `- Re: What's wrong with "char op[8]=(istest?"ef":"df");"John Forkosh

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

<ssos8v$pq3$1@reader1.panix.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=20172&group=comp.lang.c#20172

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!weretis.net!feeder6.news.weretis.net!panix!.POSTED.panix3.panix.com!not-for-mail
From: fork...@panix.com (John Forkosh)
Newsgroups: comp.lang.c
Subject: What's wrong with "char op[8]=(istest?"ef":"df");"
Date: Tue, 25 Jan 2022 13:00:15 -0000 (UTC)
Organization: PANIX Public Access Internet and UNIX, NYC
Message-ID: <ssos8v$pq3$1@reader1.panix.com>
Injection-Date: Tue, 25 Jan 2022 13:00:15 -0000 (UTC)
Injection-Info: reader1.panix.com; posting-host="panix3.panix.com:166.84.1.3";
logging-data="26435"; mail-complaints-to="abuse@panix.com"
User-Agent: tin/2.6.0-20210823 ("Coleburn") (NetBSD/9.2 (amd64))
 by: John Forkosh - Tue, 25 Jan 2022 13:00 UTC

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. I've used this construction
a million times without problems. But a-million-and-one seems
to somehow be a problem. What's wrong???
--
John Forkosh ( mailto: j@f.com where j=john and f=forkosh )

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

<ssosr4$pq3$2@reader1.panix.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=20173&group=comp.lang.c#20173

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!weretis.net!feeder6.news.weretis.net!panix!.POSTED.panix3.panix.com!not-for-mail
From: fork...@panix.com (John Forkosh)
Newsgroups: comp.lang.c
Subject: Re: What's wrong with "char op[8]=(istest?"ef":"df");"
Date: Tue, 25 Jan 2022 13:09:56 -0000 (UTC)
Organization: PANIX Public Access Internet and UNIX, NYC
Message-ID: <ssosr4$pq3$2@reader1.panix.com>
References: <ssos8v$pq3$1@reader1.panix.com>
Injection-Date: Tue, 25 Jan 2022 13:09:56 -0000 (UTC)
Injection-Info: reader1.panix.com; posting-host="panix3.panix.com:166.84.1.3";
logging-data="26435"; mail-complaints-to="abuse@panix.com"
User-Agent: tin/2.6.0-20210823 ("Coleburn") (NetBSD/9.2 (amd64))
 by: John Forkosh - Tue, 25 Jan 2022 13:09 UTC

John Forkosh <forkosh@panix.com> wrote:
.... and just to emphasize the point,
the following minimal now-working program compiles
and runs just fine

#include <stdio.h>
#include <string.h>
int main () {
int istest=1;
/*char op[8] = (istest?"ef":"df");*/
char op[8] = "ef";
strcpy(op,(istest?"df":"ef"));
printf("op=%s\n",op); }

So the (istest?"df":"ef") seems to be just fine,
as per my million-times-used expectations.
But the stoopid char op[8] = (istest?"ef":"df");
is somehow creating a problem that completely
baffles me.
--
John Forkosh ( mailto: j@f.com where j=john and f=forkosh )

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

<ssoud7$146a$1@gioia.aioe.org>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=20174&group=comp.lang.c#20174

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!aioe.org!299gYy2nqWB43X4cCBV6zg.user.46.165.242.75.POSTED!not-for-mail
From: mate...@xyz.invalid (Mateusz Viste)
Newsgroups: comp.lang.c
Subject: Re: What's wrong with "char op[8]=(istest?"ef":"df");"
Date: Tue, 25 Jan 2022 14:36:39 +0100
Organization: . . .
Message-ID: <ssoud7$146a$1@gioia.aioe.org>
References: <ssos8v$pq3$1@reader1.panix.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Injection-Info: gioia.aioe.org; logging-data="37066"; posting-host="299gYy2nqWB43X4cCBV6zg.user.gioia.aioe.org"; mail-complaints-to="abuse@aioe.org";
X-Notice: Filtered by postfilter v. 0.9.2
 by: Mateusz Viste - Tue, 25 Jan 2022 13:36 UTC

2022-01-25 at 13:00 -0000, 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. 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 do not think that an array initializer can be a conditional
expression.

Are you sure that in your million previous times you were initializing
an array, and not a pointer? ie. this should work as you expect:

#include <stdio.h>
int main () {
int istest=1;
char *op = (istest?"ef":"df");
printf("op=%s\n",op);
}

Mateusz

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

<ssovvk$urk$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=20175&group=comp.lang.c#20175

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: bc...@freeuk.com (Bart)
Newsgroups: comp.lang.c
Subject: Re: What's wrong with "char op[8]=(istest?"ef":"df");"
Date: Tue, 25 Jan 2022 14:03:33 +0000
Organization: A noiseless patient Spider
Lines: 43
Message-ID: <ssovvk$urk$1@dont-email.me>
References: <ssos8v$pq3$1@reader1.panix.com> <ssosr4$pq3$2@reader1.panix.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Tue, 25 Jan 2022 14:03:32 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="1abaccf232ce75819d12e3d24e0535e8";
logging-data="31604"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19nnygSscirxyRljsvs6yG8+kl46K90CXA="
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101
Thunderbird/91.5.0
Cancel-Lock: sha1:zyLe4DT+3IORKpGuXX0dnjJlvQg=
In-Reply-To: <ssosr4$pq3$2@reader1.panix.com>
 by: Bart - Tue, 25 Jan 2022 14:03 UTC

On 25/01/2022 13:09, John Forkosh wrote:
> John Forkosh <forkosh@panix.com> wrote:
> ... and just to emphasize the point,
> the following minimal now-working program compiles
> and runs just fine
>
> #include <stdio.h>
> #include <string.h>
> int main () {
> int istest=1;
> /*char op[8] = (istest?"ef":"df");*/
> char op[8] = "ef";
> strcpy(op,(istest?"df":"ef"));
> printf("op=%s\n",op); }
>
> So the (istest?"df":"ef") seems to be just fine,
> as per my million-times-used expectations.
> But the stoopid char op[8] = (istest?"ef":"df");
> is somehow creating a problem that completely
> baffles me.

You're initialising an array of small integers. This would normally be
done with:

{'e', 'f'};

For an array of char, and for long strings, this would involve a lot of
typing. So C allows you to represent the list using a string:

"ef";

even though this has the wrong type (char*, not char[]). It's easy to
see that you're pushing it if you further try to incorporate that into
an expression. Partly because the expression has to yield a value-array
type (char[]), which is not possible in C.

The standards experts will be along shortly to tell you exactly which
sub-section and paragraph forbids it.

Meanwhile, try changing 'char op[8]' into 'char* op', and it should
work. Your version using strcpy is manipulating char* types not char[],
that's why it works.

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

<ssp1nt$pq5$1@reader1.panix.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=20176&group=comp.lang.c#20176

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!weretis.net!feeder6.news.weretis.net!panix!.POSTED.panix3.panix.com!not-for-mail
From: fork...@panix.com (John Forkosh)
Newsgroups: comp.lang.c
Subject: Re: What's wrong with "char op[8]=(istest?"ef":"df");"
Date: Tue, 25 Jan 2022 14:33:33 -0000 (UTC)
Organization: PANIX Public Access Internet and UNIX, NYC
Message-ID: <ssp1nt$pq5$1@reader1.panix.com>
References: <ssos8v$pq3$1@reader1.panix.com> <ssosr4$pq3$2@reader1.panix.com> <ssovvk$urk$1@dont-email.me>
Injection-Date: Tue, 25 Jan 2022 14:33:33 -0000 (UTC)
Injection-Info: reader1.panix.com; posting-host="panix3.panix.com:166.84.1.3";
logging-data="26437"; mail-complaints-to="abuse@panix.com"
User-Agent: tin/2.6.0-20210823 ("Coleburn") (NetBSD/9.2 (amd64))
 by: John Forkosh - Tue, 25 Jan 2022 14:33 UTC

Bart <bc@freeuk.com> wrote:
> On 25/01/2022 13:09, John Forkosh wrote:
>> John Forkosh <forkosh@panix.com> wrote:
>> ... and just to emphasize the point,
>> the following minimal now-working program compiles
>> and runs just fine
>>
>> #include <stdio.h>
>> #include <string.h>
>> int main () {
>> int istest=1;
>> /*char op[8] = (istest?"ef":"df");*/
>> char op[8] = "ef";
>> strcpy(op,(istest?"df":"ef"));
>> printf("op=%s\n",op); }
>>
>> So the (istest?"df":"ef") seems to be just fine,
>> as per my million-times-used expectations.
>> But the stoopid char op[8] = (istest?"ef":"df");
>> is somehow creating a problem that completely
>> baffles me.
>
>
> You're initialising an array of small integers. This would normally be
> done with:
>
> {'e', 'f'};
>
> For an array of char, and for long strings, this would involve a lot of
> typing. So C allows you to represent the list using a string:
>
> "ef";
>
> even though this has the wrong type (char*, not char[]). It's easy to
> see that you're pushing it if you further try to incorporate that into
> an expression. Partly because the expression has to yield a value-array
> type (char[]), which is not possible in C.
>
> The standards experts will be along shortly to tell you exactly which
> sub-section and paragraph forbids it.
>
> Meanwhile, try changing 'char op[8]' into 'char* op', and it should
> work. Your version using strcpy is manipulating char* types not char[],
> that's why it works.

Thanks, I know for sure I've used more-or-less this type
of construction a million times, and could've sworn I'd done it
exactly this way at least a few thousand, but apparently not.
And just to check your remarks, while the char op[8] = "ef";
initialization works, when I tried what you'd (or at least me'd)
think would be the same char op[8] = (char *)"ef";
then that emitted the same invalid initializer error.
No problem, I'll just use the strcpy. I usually allocate more
bytes than I actually need in these kinds of cases, just in case
an extra character or two slips in. So I don't personally like
the char *op= solution. Anyway, thanks again for clearing it up.
--
John Forkosh ( mailto: j@f.com where j=john and f=forkosh )

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

<86mtjjnale.fsf@linuxsc.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=20177&group=comp.lang.c#20177

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: tr.17...@z991.linuxsc.com (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: <ssos8v$pq3$1@reader1.panix.com>
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=
 by: Tim Rentsch - Tue, 25 Jan 2022 14:39 UTC

John Forkosh <forkosh@panix.com> writes:

> 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. 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).

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

<ssp27g$pq5$2@reader1.panix.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=20178&group=comp.lang.c#20178

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!weretis.net!feeder6.news.weretis.net!panix!.POSTED.panix3.panix.com!not-for-mail
From: fork...@panix.com (John Forkosh)
Newsgroups: comp.lang.c
Subject: Re: What's wrong with "char op[8]=(istest?"ef":"df");"
Date: Tue, 25 Jan 2022 14:41:52 -0000 (UTC)
Organization: PANIX Public Access Internet and UNIX, NYC
Message-ID: <ssp27g$pq5$2@reader1.panix.com>
References: <ssos8v$pq3$1@reader1.panix.com> <ssoud7$146a$1@gioia.aioe.org>
Injection-Date: Tue, 25 Jan 2022 14:41:52 -0000 (UTC)
Injection-Info: reader1.panix.com; posting-host="panix3.panix.com:166.84.1.3";
logging-data="26437"; mail-complaints-to="abuse@panix.com"
User-Agent: tin/2.6.0-20210823 ("Coleburn") (NetBSD/9.2 (amd64))
 by: John Forkosh - Tue, 25 Jan 2022 14:41 UTC

Mateusz Viste <mateusz@xyz.invalid> wrote:
> 2022-01-25 at 13:00 -0000, 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. 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 do not think that an array initializer can be a conditional
> expression.
>
> Are you sure that in your million previous times you were initializing
> an array, and not a pointer? ie. this should work as you expect:
>
> #include <stdio.h>
> int main () {
> int istest=1;
> char *op = (istest?"ef":"df");
> printf("op=%s\n",op);
> }
>
> Mateusz

Thanks, Mateusz. Yeah, as you and Bart point out, my million previous
times must have been compliant with the standards. I'd of sworn I'd
done it exactly as originally illustrated, but I guess not.
--
John Forkosh ( mailto: j@f.com where j=john and f=forkosh )

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

<ssp33a$aq9$1@reader1.panix.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=20181&group=comp.lang.c#20181

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!weretis.net!feeder6.news.weretis.net!panix!.POSTED.panix3.panix.com!not-for-mail
From: fork...@panix.com (John Forkosh)
Newsgroups: comp.lang.c
Subject: Re: What's wrong with "char op[8]=(istest?"ef":"df");"
Date: Tue, 25 Jan 2022 14:56:42 -0000 (UTC)
Organization: PANIX Public Access Internet and UNIX, NYC
Message-ID: <ssp33a$aq9$1@reader1.panix.com>
References: <ssos8v$pq3$1@reader1.panix.com> <86mtjjnale.fsf@linuxsc.com>
Injection-Date: Tue, 25 Jan 2022 14:56:42 -0000 (UTC)
Injection-Info: reader1.panix.com; posting-host="panix3.panix.com:166.84.1.3";
logging-data="11081"; mail-complaints-to="abuse@panix.com"
User-Agent: tin/2.6.0-20210823 ("Coleburn") (NetBSD/9.2 (amd64))
 by: John Forkosh - Tue, 25 Jan 2022 14:56 UTC

Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
> John Forkosh <forkosh@panix.com> writes:
>
>> 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. 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' };

Thanks, Tim. That's certainly ingenious. After reading Bart's
answer, I first tried thinking/trying various syntactic fixes
to get the compiler to do what I wanted. But nothing I tried
worked, and your solution, which indeed works, never crossed
my mind.

> 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.

Yeah, that's what I'm gonna do. No need to get fancy, or anything.
If I'd just realized my blunder, I'd just have done that to begin
with, and never posted any question. I only posted because the
problem completely baffled me. The strcpy() workaround was immediately
obvious.

> 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).

Not any potential problem. The opcode syntax is fixed size,
and I've already allocated more than it'll ever need, precisely
for those "just in case" situations.
--
John Forkosh ( mailto: j@f.com where j=john and f=forkosh )

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

<ssp79k$lna$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=20182&group=comp.lang.c#20182

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: jameskuy...@alumni.caltech.edu (James Kuyper)
Newsgroups: comp.lang.c
Subject: Re: What's wrong with "char op[8]=(istest?"ef":"df");"
Date: Tue, 25 Jan 2022 11:08:19 -0500
Organization: A noiseless patient Spider
Lines: 87
Message-ID: <ssp79k$lna$1@dont-email.me>
References: <ssos8v$pq3$1@reader1.panix.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Injection-Date: Tue, 25 Jan 2022 16:08:20 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="a59f3848dc39cbe415e127036020ed39";
logging-data="22250"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/Ik2vqps5j3DCy7WrscTIK1TdHnsJqzcE="
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101
Thunderbird/91.5.0
Cancel-Lock: sha1:g5Qi3AJswnREXm0XPK9dykddLvk=
In-Reply-To: <ssos8v$pq3$1@reader1.panix.com>
Content-Language: en-US
 by: James Kuyper - Tue, 25 Jan 2022 16:08 UTC

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");

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.

> ... 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.

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

<initializer-20220125171345@ram.dialup.fu-berlin.de>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=20183&group=comp.lang.c#20183

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!usenet.goja.nl.eu.org!news.freedyn.de!speedkom.net!fu-berlin.de!uni-berlin.de!not-for-mail
From: ram...@zedat.fu-berlin.de (Stefan Ram)
Newsgroups: comp.lang.c
Subject: Re: What's wrong with "char op[8]=(istest?"ef":"df");"
Date: 25 Jan 2022 16:17:57 GMT
Organization: Stefan Ram
Lines: 21
Expires: 1 Apr 2022 11:59:58 GMT
Message-ID: <initializer-20220125171345@ram.dialup.fu-berlin.de>
References: <ssos8v$pq3$1@reader1.panix.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-Trace: news.uni-berlin.de Z3B+DG6aSrwii5mzpRr1JwPFw48XECAGuSYILVEtHCucT4
X-Copyright: (C) Copyright 2022 Stefan Ram. All rights reserved.
Distribution through any means other than regular usenet
channels is forbidden. It is forbidden to publish this
article in the Web, to change URIs of this article into links,
and to transfer the body without this notice, but quotations
of parts in other Usenet posts are allowed.
X-No-Archive: Yes
Archive: no
X-No-Archive-Readme: "X-No-Archive" is set, because this prevents some
services to mirror the article in the web. But the article may
be kept on a Usenet archive server with only NNTP access.
X-No-Html: yes
Content-Language: en-US
Accept-Language: de-DE, en-US, it, fr-FR
 by: Stefan Ram - Tue, 25 Jan 2022 16:17 UTC

John Forkosh <forkosh@panix.com> writes:
>char op[8] = (istest?"ef":"df");

Well, I find here:

|An array of character type may be initialized by a character
|string literal or UTF–8 string literal, optionally enclosed
|in braces.
....
|Otherwise, the initializer for an object that has aggregate
|or union type shall be a brace-enclosed list of initializers
|for the elements or named members.

. So, if I have not missed anything and this is the complete
list of possible ways to initialize an array of character type,
that would explain the error message!

What about "#include <string.h>" and then »char op[ 8 ];
strcpy( op, istest? "ef": "df" );«?

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

<87a6fjmogk.fsf@nosuchdomain.example.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=20194&group=comp.lang.c#20194

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: Keith.S....@gmail.com (Keith Thompson)
Newsgroups: comp.lang.c
Subject: Re: What's wrong with "char op[8]=(istest?"ef":"df");"
Date: Tue, 25 Jan 2022 14:37:31 -0800
Organization: None to speak of
Lines: 64
Message-ID: <87a6fjmogk.fsf@nosuchdomain.example.com>
References: <ssos8v$pq3$1@reader1.panix.com>
Mime-Version: 1.0
Content-Type: text/plain
Injection-Info: reader02.eternal-september.org; posting-host="fbd031f938b902ca86c8b061f35a7f8c";
logging-data="14583"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19Mvb4L4tVRS9hhv1cghJGC"
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux)
Cancel-Lock: sha1:/pQcrNxpR7xUwKQXuPq5Lufhhhs=
sha1:vUEqkhAVaWQfI2IEyFwybFaRgOs=
 by: Keith Thompson - Tue, 25 Jan 2022 22:37 UTC

John Forkosh <forkosh@panix.com> writes:
> 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. I've used this construction
> a million times without problems. But a-million-and-one seems
> to somehow be a problem. What's wrong???

The "=" symbol can be used either in an assignment or in an declaration
with an initializer. They look similar, but they're different.

For example:

int n = 42; // an declaration with an initializer
n = 42; // an assignment

The "=" in the declaration must be followed by an *initializer*, which
can be either an expression or a sequence of one or more initializers
enclosed in { ... }. The "=" in the assignment must be followed by an
expression.

A declaration like

char op[8] = "ef";

is a special case. Arrays can be initialized, but they can't be
assigned, so this:

op = "ef";

is invalid. The special case is that you can use a string literal
as the initializer for an array object (of an appropriate type).
There is no such special case for more complicated expressions like
(istest?"ef":"df").

Somewhat similarly, but following from a different set of rules, this is
valid:

int a[] = { 10, 20, 30 };

but this is not:

int a[] = cond ? { 10, 20, 30 } : { 40, 50, 60 };

because { 10, 20, 30 } is an initializer but not an expression.

--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */

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

<ssqgd4$3ab$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=20197&group=comp.lang.c#20197

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: andreyta...@hotmail.com (Andrey Tarasevich)
Newsgroups: comp.lang.c
Subject: Re: What's wrong with "char op[8]=(istest?"ef":"df");"
Date: Tue, 25 Jan 2022 19:49:56 -0800
Organization: A noiseless patient Spider
Lines: 48
Message-ID: <ssqgd4$3ab$1@dont-email.me>
References: <ssos8v$pq3$1@reader1.panix.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Wed, 26 Jan 2022 03:49:57 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="09d4fe9540222b4acb9cfb3d8b5b0976";
logging-data="3403"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18ge8OoOzDnf1vm1jgwU5f2"
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101
Thunderbird/91.5.1
Cancel-Lock: sha1:2l5uF3ojPyisVft8gZgFzKPP4PA=
In-Reply-To: <ssos8v$pq3$1@reader1.panix.com>
Content-Language: en-US
 by: Andrey Tarasevich - Wed, 26 Jan 2022 03:49 UTC

On 1/25/2022 5:00 AM, 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. I've used this construction
> a million times without problems. But a-million-and-one seems
> to somehow be a problem. What's wrong???

Not sure about the intent of your question. Are you asking how it
contradicts rules of the language? Or are you asking why the rules of
the language are written that way?

The answer to the former is that each string literal ("ef" and "df") is
an array. Arrays in C are affected by so called "array type decay": they
turn into pointers, with the exception of several immediate contexts

1. Operand of unary `&`
2. Operand of `sizeof`
3. Operand of `_Alignof`
4. String literal initializer for a `char[]` array

This why your commented-out line compiles: it is excepted from the decay
by point 4 and handled in a very special way, described in the standard.

Your original declaration is not excepted by any of these rules. So,
your literals decay to pointers. And pointers cannot be used to
initialize arrays. End of story.

As for why the language standard is written that way... Well, that's
just the way it works in C.

--
Best regards,
Andrey Tarasevich

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

<871r0vm9o6.fsf@nosuchdomain.example.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=20198&group=comp.lang.c#20198

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: Keith.S....@gmail.com (Keith Thompson)
Newsgroups: comp.lang.c
Subject: Re: What's wrong with "char op[8]=(istest?"ef":"df");"
Date: Tue, 25 Jan 2022 19:56:57 -0800
Organization: None to speak of
Lines: 26
Message-ID: <871r0vm9o6.fsf@nosuchdomain.example.com>
References: <ssos8v$pq3$1@reader1.panix.com> <ssqgd4$3ab$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain
Injection-Info: reader02.eternal-september.org; posting-host="106b8eac75c3b3e9d03a248823c06271";
logging-data="4566"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18q63IInGrPl6nsQSr4FoRe"
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux)
Cancel-Lock: sha1:7TTfi8QOKXdKHG2rjD6rdCxter8=
sha1:HGAsrO3+yzeYg3q+6mfYxPxkWPg=
 by: Keith Thompson - Wed, 26 Jan 2022 03:56 UTC

Andrey Tarasevich <andreytarasevich@hotmail.com> writes:
[...]
> The answer to the former is that each string literal ("ef" and "df")
> is an array. Arrays in C are affected by so called "array type decay":
> they turn into pointers, with the exception of several immediate
> contexts
>
> 1. Operand of unary `&`
> 2. Operand of `sizeof`
> 3. Operand of `_Alignof`
> 4. String literal initializer for a `char[]` array
[...]

The operand of _Alignof is not one of the exceptions.

It was incorrectly listed as one in the N1570 draft, but that was
corrected in the published 2011 ISO C standard.

_Alignof, unlike sizeof, can only take a parenthesized type name as an
operand, so it doesn't apply. (I don't know why _Alignof doesn't take
an expression operand.)

--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */

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

<ssqj6t$g89$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=20199&group=comp.lang.c#20199

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: jameskuy...@alumni.caltech.edu (James Kuyper)
Newsgroups: comp.lang.c
Subject: Re: What's wrong with "char op[8]=(istest?"ef":"df");"
Date: Tue, 25 Jan 2022 23:37:48 -0500
Organization: A noiseless patient Spider
Lines: 74
Message-ID: <ssqj6t$g89$1@dont-email.me>
References: <ssos8v$pq3$1@reader1.panix.com> <ssqgd4$3ab$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 7bit
Injection-Date: Wed, 26 Jan 2022 04:37:49 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="2d1a2ae672a4900b873df4b0e25d50cc";
logging-data="16649"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19pW0wDWFhJaMgi8Rnh33yoTCdliYTvaaw="
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101
Thunderbird/91.5.0
Cancel-Lock: sha1:1PMt/ehkjSmGjETkey8s3UT0hUI=
In-Reply-To: <ssqgd4$3ab$1@dont-email.me>
Content-Language: en-US
 by: James Kuyper - Wed, 26 Jan 2022 04:37 UTC

On 1/25/22 22:49, Andrey Tarasevich wrote:
> On 1/25/2022 5:00 AM, 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. I've used this construction
>> a million times without problems. But a-million-and-one seems
>> to somehow be a problem. What's wrong???
>
> Not sure about the intent of your question. Are you asking how it
> contradicts rules of the language? Or are you asking why the rules of
> the language are written that way?
>
> The answer to the former is that each string literal ("ef" and "df")
> is an array. Arrays in C are affected by so called "array type decay":
> they turn into pointers, with the exception of several immediate contexts
>
> 1. Operand of unary `&`
> 2. Operand of `sizeof`
> 3. Operand of `_Alignof`
> 4. String literal initializer for a `char[]` array
>
> This why your commented-out line compiles: it is excepted from the
> decay by point 4 and handled in a very special way, described in the
> standard.
>
> Your original declaration is not excepted by any of these rules. So,
> your literals decay to pointers. And pointers cannot be used to
> initialize arrays. End of story.
>
> As for why the language standard is written that way... Well, that's
> just the way it works in C.

Those rules are far better motivated than implied by that wording.

The implicit conversion of expressions with array type into pointers to
the first element of the array was intended to be a convenience feature.
Without that rule, since C doesn't allow passing arguments by reference,
&array[0] would have to be an excessively common construct.
The only exceptions to that rule are necessary - if they weren't
exceptions, there would be no good alternatives for achieving the same
result that they do achieve because they are exceptions.

In C, strings are not a data type, but rather a data format: an
null-terminated array of char. That string literals can be used to
initialize such an array was also a convenience feature. Without that
rule, we'd have to use:

char greeting[] = {'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r',
'l', 'd', '!', '\0'};

or

strcpy(greeting, "Hello, world!");

Unfortunately, these convenience features led to the widespread
confusion that "arrays are pointers". Less widespread is the other
misconception that is shown in this thread, that character arrays can be
initialized using a pointer to another array of the same type.

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

<ssqk5u$kfm$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=20200&group=comp.lang.c#20200

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: andreyta...@hotmail.com (Andrey Tarasevich)
Newsgroups: comp.lang.c
Subject: Re: What's wrong with "char op[8]=(istest?"ef":"df");"
Date: Tue, 25 Jan 2022 20:54:20 -0800
Organization: A noiseless patient Spider
Lines: 37
Message-ID: <ssqk5u$kfm$1@dont-email.me>
References: <ssos8v$pq3$1@reader1.panix.com> <ssqgd4$3ab$1@dont-email.me>
<ssqj6t$g89$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Wed, 26 Jan 2022 04:54:22 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="09d4fe9540222b4acb9cfb3d8b5b0976";
logging-data="20982"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+MWgZqMUJO7CgyT+UMvHdB"
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101
Thunderbird/91.5.1
Cancel-Lock: sha1:iYwVG6SKl6087cFvP8Yh8U3L1Og=
In-Reply-To: <ssqj6t$g89$1@dont-email.me>
Content-Language: en-US
 by: Andrey Tarasevich - Wed, 26 Jan 2022 04:54 UTC

On 1/25/2022 8:37 PM, James Kuyper wrote:
>>
>> As for why the language standard is written that way... Well, that's
>> just the way it works in C.
>
> Those rules are far better motivated than implied by that wording.

I didn't intend to imply that. It is just a separate story, which I'm
not sure the OP wanted to hear.

> The implicit conversion of expressions with array type into pointers to
> the first element of the array was intended to be a convenience feature.
> Without that rule, since C doesn't allow passing arguments by reference,
> &array[0] would have to be an excessively common construct.
> The only exceptions to that rule are necessary - if they weren't
> exceptions, there would be no good alternatives for achieving the same
> result that they do achieve because they are exceptions.

Dennis Ritchie in "The Development of the C Language" mentions what
appears to be a fairly different rationale. The way arrays are
implemented in C is basically the "common denominator" of the following
two objectives:

1. Preserve as much as possible source-level backward compatibility with
B language, where arrays are actually implemented through physical pointers.

2. Make arrays act as "shallow" members of struct types. Keep struct
types trivial and memcpy-copyable even when they contain arrays.

Trying to marry the two, he adopted the idea of a "non-pointer yet
happily decaying" arrays. He preserved value-context behavior of B
arrays, but changed their object-context behavior.

--
Best regards,
Andrey Tarasevich

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

<20220125204715.355@kylheku.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=20201&group=comp.lang.c#20201

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: 480-992-...@kylheku.com (Kaz Kylheku)
Newsgroups: comp.lang.c
Subject: Re: What's wrong with "char op[8]=(istest?"ef":"df");"
Date: Wed, 26 Jan 2022 05:08:36 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 102
Message-ID: <20220125204715.355@kylheku.com>
References: <ssos8v$pq3$1@reader1.panix.com>
Injection-Date: Wed, 26 Jan 2022 05:08:36 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="f7e5d410e9c70e9eec7ea17ecb88c32e";
logging-data="24974"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/3YDr3tvvYeIWhhuvxiB/FNW+isesFJK0="
User-Agent: slrn/1.0.3 (Linux)
Cancel-Lock: sha1:o4tQyEYQ/GBPHHjCgyWFqSmO3Ts=
 by: Kaz Kylheku - Wed, 26 Jan 2022 05:08 UTC

On 2022-01-25, John Forkosh <forkosh@panix.com> 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. I've used this construction
> a million times without problems. But a-million-and-one seems
> to somehow be a problem. What's wrong???

Initialization is not assignment, as others have answered.
An array of char may be initialized by a literal, and that
has special meaning.

Note that arrays cannot be assigned at all in C:

char a[5];
a = "abc"; // error

A solution which is semantically close to the apparent
intended meaning of what you're trying to do is this:

char op[8] = { istest ? 'e' : 'd', 'f' };

(This uses a non-constant expression for initializing an aggregate
member, which was not required to work in ISO C C90, but became standard
as of C99, at least for aggregates defined in automatic storage.)

By semantically close I mean that op is the the type that you seem to
want: a modifiable array of 8 characters, and that the goal of
initializing that array one way or the other based on the flag is
satisfied.

Whereas:

char *op = istest ? "ef" : "df";

is certainly succinct, op is not an array but a pointer.
Therefore sizeof (op) calculates sizeof (char *) which is
unrelated to how many characters there are in the underlyinga
array. It points to an array which is not of 8 chars but 3, and
that is not required to be modifiable; this is not well-defined
behavior, under this definition of op:

op[0] = 'g';

Another solution:

char op[8];
strcpy(op, istest ? "ef" : "df");

If istest can be a compile-time condition:

#define istest 1

#if istest
#define iftest_init(THEN, ELSE) THEN
#define iftest(THEN, ELSE) (THEN)
#else
#define iftest_init(THEN, ELSE) ELSE
#define iftest(THEN, ELSE) (ELSE)
#endif

char op[8] = iftest_init("ef", "df");

iftest() generates parentheses, which we want almost all the time,
except here; so we introduce iftest_init() which doesn't do that.

Defining "if" macros like this requires a bit of upfront verbiage,
but the resulting code can be preferrable to code like:

#if test
char op[8] = "ef";
#else
char op[8] = "df";
#endif

or even

char op[8] =
#if test
"ef"
#else
"df"
#endif
;

--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal

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

<ssr049$8ao$1@reader1.panix.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=20202&group=comp.lang.c#20202

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!weretis.net!feeder6.news.weretis.net!panix!.POSTED.panix3.panix.com!not-for-mail
From: fork...@panix.com (John Forkosh)
Newsgroups: comp.lang.c
Subject: Re: What's wrong with "char op[8]=(istest?"ef":"df");"
Date: Wed, 26 Jan 2022 08:18:17 -0000 (UTC)
Organization: PANIX Public Access Internet and UNIX, NYC
Message-ID: <ssr049$8ao$1@reader1.panix.com>
References: <ssos8v$pq3$1@reader1.panix.com> <ssp79k$lna$1@dont-email.me>
Injection-Date: Wed, 26 Jan 2022 08:18:17 -0000 (UTC)
Injection-Info: reader1.panix.com; posting-host="panix3.panix.com:166.84.1.3";
logging-data="8536"; mail-complaints-to="abuse@panix.com"
User-Agent: tin/2.6.0-20210823 ("Coleburn") (NetBSD/9.2 (amd64))
 by: John Forkosh - Wed, 26 Jan 2022 08:18 UTC

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 )

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

<ssr0ld$8ao$2@reader1.panix.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=20203&group=comp.lang.c#20203

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!weretis.net!feeder6.news.weretis.net!panix!.POSTED.panix3.panix.com!not-for-mail
From: fork...@panix.com (John Forkosh)
Newsgroups: comp.lang.c
Subject: Re: What's wrong with "char op[8]=(istest?"ef":"df");"
Date: Wed, 26 Jan 2022 08:27:25 -0000 (UTC)
Organization: PANIX Public Access Internet and UNIX, NYC
Message-ID: <ssr0ld$8ao$2@reader1.panix.com>
References: <ssos8v$pq3$1@reader1.panix.com> <87a6fjmogk.fsf@nosuchdomain.example.com>
Injection-Date: Wed, 26 Jan 2022 08:27:25 -0000 (UTC)
Injection-Info: reader1.panix.com; posting-host="panix3.panix.com:166.84.1.3";
logging-data="8536"; mail-complaints-to="abuse@panix.com"
User-Agent: tin/2.6.0-20210823 ("Coleburn") (NetBSD/9.2 (amd64))
 by: John Forkosh - Wed, 26 Jan 2022 08:27 UTC

Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
> The "=" symbol can be used either in an assignment or in an declaration
> with an initializer. They look similar, but they're different. For example:
> int n = 42; // an declaration with an initializer
> n = 42; // an assignment
> The "=" in the declaration must be followed by an *initializer*, which
> can be either an expression or a sequence of one or more initializers
> enclosed in { ... }. The "=" in the assignment must be followed by an
> expression. A declaration like
> char op[8] = "ef";
> is a special case. Arrays can be initialized, but they can't be
> assigned, so this:
> op = "ef";
> is invalid. The special case is that you can use a string literal
> as the initializer for an array object (of an appropriate type).
> There is no such special case for more complicated expressions like
> (istest?"ef":"df").
>
> Somewhat similarly, but following from a different set of rules, this is
> valid:
> int a[] = { 10, 20, 30 };
> but this is not:
> int a[] = cond ? { 10, 20, 30 } : { 40, 50, 60 };
> because { 10, 20, 30 } is an initializer but not an expression.

Interesting example. And, yeah, I'd never think of trying to write
(cond?{10,20,30}:{40,50,60}) in any context. Just doesn't look right.
Actually, though I'm apparently prone to be wrong, I'd think there
isn't any context where that would compile without error.
--
John Forkosh ( mailto: j@f.com where j=john and f=forkosh )

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

<ssr17f$8ao$3@reader1.panix.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=20205&group=comp.lang.c#20205

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!weretis.net!feeder6.news.weretis.net!panix!.POSTED.panix3.panix.com!not-for-mail
From: fork...@panix.com (John Forkosh)
Newsgroups: comp.lang.c
Subject: Re: What's wrong with "char op[8]=(istest?"ef":"df");"
Date: Wed, 26 Jan 2022 08:37:03 -0000 (UTC)
Organization: PANIX Public Access Internet and UNIX, NYC
Message-ID: <ssr17f$8ao$3@reader1.panix.com>
References: <ssos8v$pq3$1@reader1.panix.com> <ssqgd4$3ab$1@dont-email.me>
Injection-Date: Wed, 26 Jan 2022 08:37:03 -0000 (UTC)
Injection-Info: reader1.panix.com; posting-host="panix3.panix.com:166.84.1.3";
logging-data="8536"; mail-complaints-to="abuse@panix.com"
User-Agent: tin/2.6.0-20210823 ("Coleburn") (NetBSD/9.2 (amd64))
 by: John Forkosh - Wed, 26 Jan 2022 08:37 UTC

Andrey Tarasevich <andreytarasevich@hotmail.com> wrote:
> Not sure about the intent of your question. Are you asking how it
> contradicts rules of the language? Or are you asking why the rules of
> the language are written that way?

Neither... just asking "if it contradicts". I'd been sure it was okay,
and spent like 5 minutes looking for a missing ; or something to
explain why it was throwing the error. Only when I gave up and
separately wrote that 5-line "minimal (non-)working example" did
I realize it was itself an error.

> The answer to the former is that each string literal ("ef" and "df") is
> an array. Arrays in C are affected by so called "array type decay": they
> turn into pointers, with the exception of several immediate contexts
>
> 1. Operand of unary `&`
> 2. Operand of `sizeof`
> 3. Operand of `_Alignof`
> 4. String literal initializer for a `char[]` array
>
> This why your commented-out line compiles: it is excepted from the decay
> by point 4 and handled in a very special way, described in the standard.
>
> Your original declaration is not excepted by any of these rules. So,
> your literals decay to pointers. And pointers cannot be used to
> initialize arrays. End of story.
>
> As for why the language standard is written that way... Well, that's
> just the way it works in C.

Yeah, "why" stopped bothering me long ago. There are various grammatical
rules that don't quite jibe with my personal sensibilities, but I've
got more pressing issues than arguing about them. Just need to know what
they are, which in this case I didn't.
--
John Forkosh ( mailto: j@f.com where j=john and f=forkosh )

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

<ssr3rs$m3n$1@reader1.panix.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=20207&group=comp.lang.c#20207

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!weretis.net!feeder6.news.weretis.net!panix!.POSTED.panix3.panix.com!not-for-mail
From: fork...@panix.com (John Forkosh)
Newsgroups: comp.lang.c
Subject: Re: What's wrong with "char op[8]=(istest?"ef":"df");"
Date: Wed, 26 Jan 2022 09:22:04 -0000 (UTC)
Organization: PANIX Public Access Internet and UNIX, NYC
Message-ID: <ssr3rs$m3n$1@reader1.panix.com>
References: <ssos8v$pq3$1@reader1.panix.com> <20220125204715.355@kylheku.com>
Injection-Date: Wed, 26 Jan 2022 09:22:04 -0000 (UTC)
Injection-Info: reader1.panix.com; posting-host="panix3.panix.com:166.84.1.3";
logging-data="22647"; mail-complaints-to="abuse@panix.com"
User-Agent: tin/2.6.0-20210823 ("Coleburn") (NetBSD/9.2 (amd64))
 by: John Forkosh - Wed, 26 Jan 2022 09:22 UTC

Kaz Kylheku <480-992-1380@kylheku.com> wrote:
> Initialization is not assignment, as others have answered.
> An array of char may be initialized by a literal, and that
> has special meaning. Note that arrays cannot be assigned
> at all in C:
> char a[5];
> a = "abc"; // error
> A solution which is semantically close to the apparent
> intended meaning of what you're trying to do is this:
> char op[8] = { istest ? 'e' : 'd', 'f' };

Yeah, Tim already suggested this alternative.
Way too ugly. Maybe okay as an isolated line,
but in 500+ lines you don't want to have to pause
for 5+ secs figuring out the intent of one little line.

> (This uses a non-constant expression for initializing an aggregate
> member, which was not required to work in ISO C C90, but became standard
> as of C99, at least for aggregates defined in automatic storage.)
>
> By semantically close I mean that op is the the type that you seem to
> want: a modifiable array of 8 characters,

Yes, exactly. Glad you noticed, and I >>should<< have (but neglected
to) mentioned that earlier myself. char op[8]="ef"; where the 'f' means
read from a file, whereas after that initial read, subsequent passes
typically change op[1]='b' to read from an internal buffer.
So, as you point out below, char *op="ef"; compiles okay but won't
work... which is another kind of error I also discovered the hard way,
a long, long time ago (but in a relatively nearby galaxy).

> and that the goal of
> initializing that array one way or the other based on the flag is
> satisfied. Whereas:
> char *op = istest ? "ef" : "df";
> is certainly succinct, op is not an array but a pointer.
> Therefore sizeof (op) calculates sizeof (char *) which is
> unrelated to how many characters there are in the underlyinga
> array. It points to an array which is not of 8 chars but 3, and
> that is not required to be modifiable; this is not well-defined
> behavior, under this definition of op:
> op[0] = 'g';

You seem to have forgotten to add the subsequent "won't work" phrase,
though that's obviously what you meant. And thanks for mentioning it,
which prompted and reminded me to add my immediately preceding remarks.
And sorry to everybody else who suggested that char *op...; solution
for not mentioning it sooner.

> Another solution:
> char op[8];
> strcpy(op, istest ? "ef" : "df");
Yup, that's what I've done.

> If istest can be a compile-time condition:
> #define istest 1
> #if istest
> #define iftest_init(THEN, ELSE) THEN
> #define iftest(THEN, ELSE) (THEN)
> #else
> #define iftest_init(THEN, ELSE) ELSE
> #define iftest(THEN, ELSE) (ELSE)
> #endif
> char op[8] = iftest_init("ef", "df");
> iftest() generates parentheses, which we want almost all the time,
> except here; so we introduce iftest_init() which doesn't do that.
> Defining "if" macros like this requires a bit of upfront verbiage,

You think??? Very cute, and maybe if I were initializing tons
of stuff this way it'd be useful.

> but the resulting code can be preferrable to code like:
> #if test
> char op[8] = "ef";
> #else
> char op[8] = "df";
> #endif
> or even
> char op[8] =
> #if test
> "ef"
> #else
> "df"
> #endif
> ;

Actually, that second way is how I typically initialize stuff like
static int msglevel =
#if defined(MSGLEVEL) /* if cc -DMSGLEVEL=nn */
MSGLEVEL;
#else
3;
#endif
(you recall the parameters on the jcl //job card?:)
--
John Forkosh ( mailto: j@f.com where j=john and f=forkosh )

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

<ssr3vq$m3n$2@reader1.panix.com>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=20208&group=comp.lang.c#20208

  copy link   Newsgroups: comp.lang.c
Path: i2pn2.org!i2pn.org!weretis.net!feeder6.news.weretis.net!panix!.POSTED.panix3.panix.com!not-for-mail
From: fork...@panix.com (John Forkosh)
Newsgroups: comp.lang.c
Subject: Re: What's wrong with "char op[8]=(istest?"ef":"df");"
Date: Wed, 26 Jan 2022 09:24:11 -0000 (UTC)
Organization: PANIX Public Access Internet and UNIX, NYC
Message-ID: <ssr3vq$m3n$2@reader1.panix.com>
References: <ssos8v$pq3$1@reader1.panix.com> <initializer-20220125171345@ram.dialup.fu-berlin.de>
Injection-Date: Wed, 26 Jan 2022 09:24:11 -0000 (UTC)
Injection-Info: reader1.panix.com; posting-host="panix3.panix.com:166.84.1.3";
logging-data="22647"; mail-complaints-to="abuse@panix.com"
User-Agent: tin/2.6.0-20210823 ("Coleburn") (NetBSD/9.2 (amd64))
 by: John Forkosh - Wed, 26 Jan 2022 09:24 UTC

Stefan Ram <ram@zedat.fu-berlin.de> wrote:
> John Forkosh <forkosh@panix.com> writes:
>>char op[8] = (istest?"ef":"df");
>
> Well, I find here:
>
> |An array of character type may be initialized by a character
> |string literal or UTF???8 string literal, optionally enclosed
> |in braces.
> ...
> |Otherwise, the initializer for an object that has aggregate
> |or union type shall be a brace-enclosed list of initializers
> |for the elements or named members.
>
> . So, if I have not missed anything and this is the complete
> list of possible ways to initialize an array of character type,
> that would explain the error message!
>
> What about "#include <string.h>" and then ??char op[ 8 ];
> strcpy( op, istest? "ef": "df" );???

Thanks, yeah, that's what I did to fix it, even before
posting here and realizing why the initialization was failing.
--
John Forkosh ( mailto: j@f.com where j=john and f=forkosh )

1
server_pubkey.txt

rocksolid light 0.9.8
clearnet tor