Path: csiph.com!eternal-september.org!feeder.eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail
From: Tim Rentsch
Newsgroups: comp.lang.c
Subject: Re: does char *str="abcd"; alloc addressable memory?
Date: Thu, 09 Jul 2020 10:07:54 -0700
Organization: A noiseless patient Spider
Lines: 56
Message-ID: <86k0zcfwgl.fsf@linuxsc.com>
References: <372e8d3b-52d6-4114-b893-6512633f5c9co@googlegroups.com> <86eepnh2wk.fsf@linuxsc.com> <87h7uj9s14.fsf@nosuchdomain.example.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Injection-Info: reader02.eternal-september.org; posting-host="c87a676e1fef5793b5d15a831e4eb134"; logging-data="30408"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18BO/e1FS0k6X2CFBqeH1izovrXhN+AUtI="
User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Cancel-Lock: sha1:eyTa+fHV5GHkMd5Bl4XD2+JSozc= sha1:up0N9cU0kZ0UmMoNsK7YKA6mLyo=
Xref: csiph.com comp.lang.c:153162
Keith Thompson writes:
> Tim Rentsch writes:
>
>> John Forkosh writes:
>>
>>> Malcolm McLean wrote:
>>>
>>>> On Monday, 6 July 2020 12:57:06 UTC+1, Bonita Montero wrote:
>>>>
>>>>> The compiler should give you an error for casting a string-literal to
>>>>> a pointer to non-const characters. If cou cast it explicitly you may
>>>>> modify the caracters and that usually works, but it's not guaranteeed.
>>>>> Most platforms will make a writable copy of a read-only mapped page.
>>>>
>>>> It doesn't warn because const was a late addition to C, and string
>>>> literals were originally char *s.
>>>> You can declare a writeable string with
>>>>
>>>> char writeable[] = "Overwrite me";
>>>>
>>>> this is also seldom a good idea.
>>>
>>> As mentioned upthread
>>> char *str = ( argc>1? argv[1] : (char *)"01234&56789" );
>>> compiles without the -Wwrite-strings warning, but still
>>> segfaults. And
>>> char str[] = ( argc>1? argv[1] : "01234&56789" );
>>> gives an error
>>> tester.c:7:16: error: invalid initializer
>>> 7 | char str[] = ( argc>1? argv[1] : "01234&56789" );
>>> | ^
>>>
>>> As suggested downthread, I can easily
>>> char default[99] = "whatever",
>>> *str = ( argc>1? argv[1] : default );
>>> but I'd prefer the more compact notation if possible.
>>> Any way to get that to work?
>>
>> It's compound literals to the rescue!
>>
>> char *str = argc > 1 ? argv[1] : (char[]){ "01234&56789" };
>>
>> No errors, no undefined behavior, no problem.
>
> One thing to keep in mind is that the object created by a compound
> literal has automatic storage duration. In this case I don't think
> that matters, but it is a difference between string literals and
> compound literals. (A compound literal outside a function body
> creates an object with static storage duration.)
Yes, good point, and that is worth both knowing and remembering.
I didn't mention it only because the declaration in question
occurs right at the start of main() and so it will not, in this
case, be a problem. But it is important to know for other
potential uses.