Deutsch English Français Italiano |
<v8gi7i$29iu1$1@dont-email.me> View for Bookmarking (what is this?) Look up another Usenet article |
Path: ...!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: Thu, 1 Aug 2024 19:56:00 +0200 Organization: A noiseless patient Spider Lines: 69 Message-ID: <v8gi7i$29iu1$1@dont-email.me> References: <IoGcndcJ1Zm83zb7nZ2dnZfqnPWdnZ2d@brightview.co.uk> <20240801174026.00002cda@yahoo.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Injection-Date: Thu, 01 Aug 2024 19:56:02 +0200 (CEST) Injection-Info: dont-email.me; posting-host="c2be0f8328bb4a6f821d6fc2990b798d"; logging-data="2411457"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+avF874XpQ1uba0667hoIcx7ftcLMNHmE=" User-Agent: Mozilla Thunderbird Cancel-Lock: sha1:xWHq76IFVfDLRUyKfY42qpPxg6E= Content-Language: en-GB, nb-NO In-Reply-To: <20240801174026.00002cda@yahoo.com> Bytes: 3866 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.