Deutsch   English   Français   Italiano  
<v8lqsc$3i80j$1@dont-email.me>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: ...!2.eu.feeder.erje.net!feeder.erje.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: David Brown <david.brown@hesbynett.no>
Newsgroups: comp.lang.c
Subject: Re: No warning at implicit removal of const. Was: relearning C: why
 does an in-place change to a char* segfault?
Date: Sat, 3 Aug 2024 19:54:20 +0200
Organization: A noiseless patient Spider
Lines: 83
Message-ID: <v8lqsc$3i80j$1@dont-email.me>
References: <IoGcndcJ1Zm83zb7nZ2dnZfqnPWdnZ2d@brightview.co.uk>
 <20240801174026.00002cda@yahoo.com> <v8gi7i$29iu1$1@dont-email.me>
 <slrnvaorkl.34j6.candycanearter07@candydeb.host.invalid>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Sat, 03 Aug 2024 19:54:23 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="b209585f2ada3beb09365cfb8283ed97";
	logging-data="3743763"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX18uIlLlMa85CueVcvsc4zecBIjHPNixs2o="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:KkijRPbx9eV6Sgu9U4QLhitOTHA=
Content-Language: en-GB, nb-NO
In-Reply-To: <slrnvaorkl.34j6.candycanearter07@candydeb.host.invalid>
Bytes: 4809

On 02/08/2024 07:30, candycanearter07 wrote:
> David Brown <david.brown@hesbynett.no> wrote at 17:56 this Thursday (GMT):
>> On 01/08/2024 16:40, Michael S wrote:
>>> On Thu, 01 Aug 2024 08:06:57 +0000
>>> Mark Summerfield <mark@qtrac.eu> wrote:
>>>
>>>> This program segfaults at the commented line:
>>>>
>>>> #include <ctype.h>
>>>> #include <stdio.h>
>>>>
>>>> void uppercase_ascii(char *s) {
>>>>       while (*s) {
>>>>           *s = toupper(*s); // SEGFAULT
>>>>           s++;
>>>>       }
>>>> }
>>>>
>>>> int main() {
>>>>       char* text = "this is a test";
>>>>       printf("before [%s]\n", text);
>>>>       uppercase_ascii(text);
>>>>       printf("after  [%s]\n", text);
>>>> }
>>>>
>>>
>>> The answers to your question are already given above, so I'd talk about
>>> something else. Sorry about it.
>>>
>>> To my surprise, none of the 3 major compilers that I tried issued the
>>> warning at this line:
>>>     char* text = "this is a test";
>>> If implicit conversion of 'const char*' to 'char*' does not warrant
>>> compiler warning than I don't know what does.
>>> Is there something in the Standard that explicitly forbids diagnostic
>>> for this sort of conversion?
>>>
>>> BTW, all 3 compilers issue reasonable warnings when I write it slightly
>>> differently:
>>>     const char* ctext = "this is a test";
>>>     char* text = ctext;
>>>
>>> I am starting to suspect that compilers (and the Standard?) consider
>>> string literals as being of type 'char*' rather than 'const char*'.
>>>
>>
>> Your suspicions are correct - in C, string literals are used to
>> initialise an array of char (or wide char, or other appropriate
>> character type).  Perhaps you are thinking of C++, where the type is
>> "const char" (or other const character type).
>>
>> So in C, when a string literal is used in an expression it is converted
>> to a "char *" pointer.  You can, of course, assign that to a "const char
>> *" pointer.  But it does not make sense to have a warning when assigning
>> it to a non-const "char *" pointer.  This is despite it being undefined
>> behaviour (explicitly stated in the standards) to attempt to write to a
>> string literal.
>>
>> The reason string literals are not const in C is backwards compatibility
>> - they existed before C had "const", and making string literals into
>> "const char" arrays would mean that existing code that assigned them to
>> non-const pointers would then be in error.  C++ was able to do the right
>> thing and make them arrays of const char because it had "const" from the
>> beginning.
>>
>> gcc has the option "-Wwrite-strings" that makes string literals in C
>> have "const char" array type, and thus give errors when you try to
>> assign to a non-const char * pointer.  But the option has to be
>> specified explicitly (it is not in -Wall) because it changes the meaning
>> of the code and can cause compatibility issues with existing correct code.
> 
> 
> -Wwrite-strings is included in -Wpedantic.

No, it is not - which is a good thing, because -Wpedantic should not 
include features that change the semantics of the language!  (IMHO the 
flag should not be called -Wwrite-strings, but -fconst-string-literals 
or similar.  It's not really a normal warning option.)

For C++, -pedantic-errors includes the -Wwrite-strings flag which then 
makes implicit conversion of string literal expressions to non-const 
char* pointers an error.  But that's C++, not C.