Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #6574 > unrolled thread
| Started by | yugandhar <nospam@nospam.com> |
|---|---|
| First post | 2011-06-21 21:49 +0000 |
| Last post | 2011-06-21 21:29 -0500 |
| Articles | 20 on this page of 53 — 20 participants |
Back to article view | Back to comp.lang.c
int * vs char * yugandhar <nospam@nospam.com> - 2011-06-21 21:49 +0000
Re: int * vs char * John Gordon <gordon@panix.com> - 2011-06-21 21:58 +0000
Re: int * vs char * "Morris Keesan" <mkeesan@post.harvard.edu> - 2011-06-21 20:25 -0400
Re: int * vs char * Ian Collins <ian-news@hotmail.com> - 2011-06-22 09:59 +1200
Re: int * vs char * Ike Naar <ike@sverige.freeshell.org> - 2011-06-21 22:18 +0000
Re: int * vs char * Shao Miller <sha0.miller@gmail.com> - 2011-06-21 18:34 -0500
Re: int * vs char * Keith Thompson <kst-u@mib.org> - 2011-06-21 15:42 -0700
Re: int * vs char * Noob <root@127.0.0.1> - 2011-06-22 10:28 +0200
Re: int * vs char * Shao Miller <sha0.miller@gmail.com> - 2011-06-22 05:23 -0500
Re: int * vs char * James Kuyper <jameskuyper@verizon.net> - 2011-06-22 06:25 -0400
Re: int * vs char * Ian Collins <ian-news@hotmail.com> - 2011-06-23 07:56 +1200
Re: int * vs char * Shao Miller <sha0.miller@gmail.com> - 2011-06-22 18:12 -0500
Re: int * vs char * Ian Collins <ian-news@hotmail.com> - 2011-06-23 10:23 +1200
Re: int * vs char * Keith Thompson <kst-u@mib.org> - 2011-06-22 17:23 -0700
Re: int * vs char * Ian Collins <ian-news@hotmail.com> - 2011-06-23 12:54 +1200
Re: int * vs char * Keith Thompson <kst-u@mib.org> - 2011-06-22 18:18 -0700
Re: int * vs char * Ian Collins <ian-news@hotmail.com> - 2011-06-23 13:23 +1200
Re: int * vs char * Shao Miller <sha0.miller@gmail.com> - 2011-06-24 15:39 -0400
Re: int * vs char * Ian Collins <ian-news@hotmail.com> - 2011-06-25 09:28 +1200
Re: int * vs char * Keith Thompson <kst-u@mib.org> - 2011-06-24 14:58 -0700
Re: int * vs char * Ian Collins <ian-news@hotmail.com> - 2011-06-25 10:06 +1200
Re: int * vs char * Shao Miller <sha0.miller@gmail.com> - 2011-06-26 15:44 -0500
Re: int * vs char * Keith Thompson <kst-u@mib.org> - 2011-06-24 14:29 -0700
Re: int * vs char * Ian Collins <ian-news@hotmail.com> - 2011-06-25 09:36 +1200
Re: int * vs char * Shao Miller <sha0.miller@gmail.com> - 2011-06-26 16:24 -0500
Re: int * vs char * Tim Rentsch <txr@alumni.caltech.edu> - 2011-06-25 08:39 -0700
Re: int * vs char * gordonb.5qick@burditt.org (Gordon Burditt) - 2011-06-22 23:49 -0500
Re: int * vs char * Stephen Sprunk <stephen@sprunk.org> - 2011-06-22 11:31 -0500
Re: int * vs char * gordonb.idn9q@burditt.org (Gordon Burditt) - 2011-06-23 00:45 -0500
Re: int * vs char * pacman@kosh.dhis.org (Alan Curry) - 2011-06-23 20:08 +0000
Re: int * vs char * Stephen Sprunk <stephen@sprunk.org> - 2011-06-23 22:40 -0500
Re: int * vs char * Ian Collins <ian-news@hotmail.com> - 2011-06-24 15:46 +1200
Re: int * vs char * Stephen Sprunk <stephen@sprunk.org> - 2011-06-24 09:24 -0500
Re: int * vs char * Shao Miller <sha0.miller@gmail.com> - 2011-07-04 18:00 -0400
Re: int * vs char * Dr Nick <3-nospam@temporary-address.org.uk> - 2011-07-05 07:45 +0100
Re: int * vs char * Harald van Dijk <truedfx@gmail.com> - 2011-07-05 10:39 -0700
Re: int * vs char * Shao Miller <sha0.miller@gmail.com> - 2011-07-05 14:09 -0400
Re: int * vs char * Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-07-07 21:56 +0300
Re: int * vs char * Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-07-08 02:46 +0300
Re: int * vs char * Shao Miller <sha0.miller@gmail.com> - 2011-07-07 22:26 -0400
Re: int * vs char * Stephen Sprunk <stephen@sprunk.org> - 2011-07-07 22:41 -0500
Re: int * vs char * "Joel C. Salomon" <joelcsalomon@gmail.com> - 2011-07-05 15:32 -0400
Re: int * vs char * Shao Miller <sha0.miller@gmail.com> - 2011-07-06 09:58 -0400
Re: int * vs char * Tim Rentsch <txr@alumni.caltech.edu> - 2011-06-23 01:02 -0700
Re: int * vs char * Ian Collins <ian-news@hotmail.com> - 2011-06-23 20:11 +1200
Re: int * vs char * Tim Rentsch <txr@alumni.caltech.edu> - 2011-06-25 09:23 -0700
Re: int * vs char * Keith Thompson <kst-u@mib.org> - 2011-06-25 12:37 -0700
Re: int * vs char * Tim Rentsch <txr@alumni.caltech.edu> - 2011-06-27 11:40 -0700
Re: int * vs char * Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-06-21 21:46 -0400
Re: int * vs char * "Kleuskes & Moos" <kleuske@xs4all.nl> - 2011-06-22 10:06 -0700
Re: int * vs char * Keith Thompson <kst-u@mib.org> - 2011-06-22 13:06 -0700
Re: int * vs char * "Kleuskes & Moos" <kleuske@xs4all.nl> - 2011-06-22 13:29 -0700
Re: int * vs char * Stephen Sprunk <stephen@sprunk.org> - 2011-06-21 21:29 -0500
Page 1 of 3 [1] 2 3 Next page →
| From | yugandhar <nospam@nospam.com> |
|---|---|
| Date | 2011-06-21 21:49 +0000 |
| Subject | int * vs char * |
| Message-ID | <itr3lm$i8j$1@speranza.aioe.org> |
Hi Forum, I have a quick question. The following works: char *s="hello"; *s="world"; but the following gives a segementation fault: int *p = 0; *p = 17; Could anyone please clarify me about this? yugandhar
[toc] | [next] | [standalone]
| From | John Gordon <gordon@panix.com> |
|---|---|
| Date | 2011-06-21 21:58 +0000 |
| Message-ID | <itr46q$243$1@reader1.panix.com> |
| In reply to | #6574 |
In <itr3lm$i8j$1@speranza.aioe.org> yugandhar <nospam@nospam.com> writes:
> Hi Forum,
> I have a quick question.
> The following works:
> char *s="hello";
> *s="world";
It shouldn't work. A character pointer declared in that way should be
non-writable. It's an accident that it "worked" (did the wrong thing)
for you.
> but the following gives a segementation fault:
> int *p = 0;
> *p = 17;
> Could anyone please clarify me about this?
Setting a pointer equal to zero is a special case.
Zero is another way of saying NULL. So when you declare a pointer that
is equal to zero, it's really a NULL pointer. It doesn't point anywhere.
So, when you say "Insert 17 at the location pointed to by this pointer",
it has no place to put the value 17, since you told it to point nowhere.
--
John Gordon A is for Amy, who fell down the stairs
gordon@panix.com B is for Basil, assaulted by bears
-- Edward Gorey, "The Gashlycrumb Tinies"
[toc] | [prev] | [next] | [standalone]
| From | "Morris Keesan" <mkeesan@post.harvard.edu> |
|---|---|
| Date | 2011-06-21 20:25 -0400 |
| Message-ID | <op.vxgbg2m85qv6o3@toshiba-laptop> |
| In reply to | #6577 |
On Tue, 21 Jun 2011 17:58:50 -0400, John Gordon <gordon@panix.com> wrote: > In <itr3lm$i8j$1@speranza.aioe.org> yugandhar <nospam@nospam.com> writes: > >> Hi Forum, > >> I have a quick question. > >> The following works: > >> char *s="hello"; >> *s="world"; > > It shouldn't work. A character pointer declared in that way should be > non-writable. It's an accident that it "worked" (did the wrong thing) > for you. Not the declaration, but the initialization (making s point to a string literal). But whether the pointed-to char is writable is undefined: "should be non-writable" is a bit of an overstatement. But it should be treated as unwritable by the programmer, even if not by an implementation. -- Morris Keesan -- mkeesan@post.harvard.edu
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-06-22 09:59 +1200 |
| Message-ID | <96ciivFmtvU2@mid.individual.net> |
| In reply to | #6574 |
On 06/22/11 09:49 AM, yugandhar wrote: > Hi Forum, > > I have a quick question. > > The following works: > > char *s="hello"; > *s="world"; It is certainly not guaranteed to work. It would barf on any of the compilers I use. These all place string literals in a write only segment. > but the following gives a segementation fault: > > int *p = 0; > *p = 17; > > Could anyone please clarify me about this? You are invoking the demons of undefined behaviour. -- Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Ike Naar <ike@sverige.freeshell.org> |
|---|---|
| Date | 2011-06-21 22:18 +0000 |
| Message-ID | <slrn3vfsj0266a.1tm.ike@sverige.freeshell.org> |
| In reply to | #6574 |
On 2011-06-21, yugandhar <nospam@nospam.com> wrote: > The following works: In what way do you think it works? > char *s="hello"; > *s="world"; You're assigning a pointer-to-char to a char. That doesn't work. Your compiler should have issued a diagnostic. > but the following gives a segementation fault: > > int *p = 0; > *p = 17; p is a null pointer; you're trying to dereference it; don't do that. > Could anyone please clarify me about this? Sorry.
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2011-06-21 18:34 -0500 |
| Message-ID | <itr69k$f7h$1@dont-email.me> |
| In reply to | #6574 |
On 6/21/2011 4:49 PM, yugandhar wrote:
> Hi Forum,
>
> I have a quick question.
>
> The following works:
>
> char *s="hello";
> *s="world";
>
The type of 's' is 'char *'.
The type of '*s' is 'char'.
The type of '"world"' is not 'char'.
So the last line up above is erroneous.
> but the following gives a segementation fault:
>
> int *p = 0;
> *p = 17;
>
The type of 'p' is 'int *'.
The type of '*p' is 'int'.
Since 'p' is a null pointer, use of '*p' is undefined behaviour. That
explains your segmentation fault.
> Could anyone please clarify me about this?
Maybe.
int my_int = 13;
^^^--type
int my_int = 13;
^^^^^^--object identifier
int * foo, * bar;
^^^-^--type
int * foo, * bar;
^^^--object identifier
int * foo, * bar;
^^^--------^--type
int * foo, * bar;
^^^--object identifier
Also:
int my_int = 13;
is similar to:
int my_int;
my_int = 13;
A different example:
int * ip = &my_int;
is similar to:
int * ip;
ip = &my_int;
and not:
int * ip;
*ip = &my_int;
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-06-21 15:42 -0700 |
| Message-ID | <lnliwuiz7c.fsf@nuthaus.mib.org> |
| In reply to | #6574 |
yugandhar <nospam@nospam.com> writes:
> I have a quick question.
>
> The following works:
>
> char *s="hello";
> *s="world";
>
> but the following gives a segementation fault:
>
> int *p = 0;
> *p = 17;
>
> Could anyone please clarify me about this?
It's already been explained why "*p = 17;" blows up, but I don't believe
that the first block of code is what you actually compiled.
s is of type char*, so *s is of type char. You're attempting to assign
a string literal (which will decay to char*) to a char object. Early
pre-ANSI C compilers might have accepted that without complaint,
implicitly treating the pointer value as an integer and then narrowing
it to one byte, but in modern C it's a constraint violation, and any
compiler that doesn't at least warn you about it is broken.
Even if you corrected the type mismatch by writing:
*s = 'w';
your program's behavior would be undefined. s points to a string
literal (more precisely, it points to the first element of the static
array associated with the string literal), and any attempt to modify a
string literal has undefined behavior.
I can't be sure what your actual code looks like, but the most plausible
variant I can think of is:
char *s = "hello";
s = "world";
That's perfectly legal; it stores the address of the string "world" in
the variable s.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Noob <root@127.0.0.1> |
|---|---|
| Date | 2011-06-22 10:28 +0200 |
| Message-ID | <its93d$62e$1@dont-email.me> |
| In reply to | #6584 |
Keith Thompson wrote: > Even if you corrected the type mismatch by writing: > > char *s = "hello"; > *s = 'w'; > > your program's behavior would be undefined. s points to a string > literal (more precisely, it points to the first element of the static > array associated with the string literal), and any attempt to modify a > string literal has undefined behavior. Since modifying a character string literal already has UB in the current standard, then why doesn't the next standard specify that string literal have type const char[] instead of just char[] ? Regards.
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2011-06-22 05:23 -0500 |
| Message-ID | <itscav$ojf$1@dont-email.me> |
| In reply to | #6597 |
On 6/22/2011 3:28 AM, Noob wrote: > Keith Thompson wrote: > >> Even if you corrected the type mismatch by writing: >> >> char *s = "hello"; >> *s = 'w'; >> >> your program's behavior would be undefined. s points to a string >> literal (more precisely, it points to the first element of the static >> array associated with the string literal), and any attempt to modify a >> string literal has undefined behavior. > > Since modifying a character string literal already has UB in > the current standard, then why doesn't the next standard > specify that string literal have type const char[] instead > of just char[] ? Undefined behaviour implies "non-portable," in my view. But why remove an implementation's freedom to define string literals' storage as writable?
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-06-22 06:25 -0400 |
| Message-ID | <itsfv5$e9l$1@dont-email.me> |
| In reply to | #6597 |
On 06/22/2011 04:28 AM, Noob wrote: ... > Since modifying a character string literal already has UB in > the current standard, then why doesn't the next standard > specify that string literal have type const char[] instead > of just char[] ? It would break a large amount of existing code. The most common problem would be code which assigns the pointer value of a string literal to a char* object. You could argue that this is bad practice - if a pointer might be pointing at a string literal, it should be declared 'const char*', rather than 'char*'. However, there's no actual problem with such code so long as no attempt is made to write through that pointer value, and there's an awful lot of existing code which relies upon that fact. -- James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-06-23 07:56 +1200 |
| Message-ID | <96evn3FmtvU8@mid.individual.net> |
| In reply to | #6602 |
On 06/22/11 10:25 PM, James Kuyper wrote: > On 06/22/2011 04:28 AM, Noob wrote: > ... >> Since modifying a character string literal already has UB in >> the current standard, then why doesn't the next standard >> specify that string literal have type const char[] instead >> of just char[] ? > > It would break a large amount of existing code. The most common problem > would be code which assigns the pointer value of a string literal to a > char* object. You could argue that this is bad practice - if a pointer > might be pointing at a string literal, it should be declared 'const > char*', rather than 'char*'. However, there's no actual problem with > such code so long as no attempt is made to write through that pointer > value, and there's an awful lot of existing code which relies upon that > fact. The existing code problem was a acknowledged when C++ changed the type of string literals. Compilers may choose not to issues a diagnostic for this case. Now we have had over a decade to fix the smelly code, I believe a diagnostic is now required by the new C++ standard. C could and should have done the same, but as usual those worried about breaking already broken code appear to have won the day. -- Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2011-06-22 18:12 -0500 |
| Message-ID | <ittpbt$k92$1@dont-email.me> |
| In reply to | #6648 |
On 6/22/2011 2:56 PM, Ian Collins wrote: > On 06/22/11 10:25 PM, James Kuyper wrote: >> On 06/22/2011 04:28 AM, Noob wrote: >> ... >>> Since modifying a character string literal already has UB in >>> the current standard, then why doesn't the next standard >>> specify that string literal have type const char[] instead >>> of just char[] ? >> >> It would break a large amount of existing code. The most common problem >> would be code which assigns the pointer value of a string literal to a >> char* object. You could argue that this is bad practice - if a pointer >> might be pointing at a string literal, it should be declared 'const >> char*', rather than 'char*'. However, there's no actual problem with >> such code so long as no attempt is made to write through that pointer >> value, and there's an awful lot of existing code which relies upon that >> fact. > > The existing code problem was a acknowledged when C++ changed the type > of string literals. Compilers may choose not to issues a diagnostic for > this case. Now we have had over a decade to fix the smelly code, I > believe a diagnostic is now required by the new C++ standard. > > C could and should have done the same, but as usual those worried about > breaking already broken code appear to have won the day. > Again, why should a C implementation be rendered non-conforming [to some future Standard] thusly? In a "bare metal" environment, one might very well wish to overwrite their string literals' storage, no? The "bare metal" implementation might need to define such action as being appropriate. By using "proper" static arrays, we lose out on the "shared storage" benefit. Writing for bare metal, hopefully one knows what one is doing. Is this example silly?
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-06-23 10:23 +1200 |
| Message-ID | <96f8b3FmtvU10@mid.individual.net> |
| In reply to | #6673 |
On 06/23/11 11:12 AM, Shao Miller wrote: > On 6/22/2011 2:56 PM, Ian Collins wrote: >> On 06/22/11 10:25 PM, James Kuyper wrote: >>> On 06/22/2011 04:28 AM, Noob wrote: >>> ... >>>> Since modifying a character string literal already has UB in >>>> the current standard, then why doesn't the next standard >>>> specify that string literal have type const char[] instead >>>> of just char[] ? >>> >>> It would break a large amount of existing code. The most common problem >>> would be code which assigns the pointer value of a string literal to a >>> char* object. You could argue that this is bad practice - if a pointer >>> might be pointing at a string literal, it should be declared 'const >>> char*', rather than 'char*'. However, there's no actual problem with >>> such code so long as no attempt is made to write through that pointer >>> value, and there's an awful lot of existing code which relies upon that >>> fact. >> >> The existing code problem was a acknowledged when C++ changed the type >> of string literals. Compilers may choose not to issues a diagnostic for >> this case. Now we have had over a decade to fix the smelly code, I >> believe a diagnostic is now required by the new C++ standard. >> >> C could and should have done the same, but as usual those worried about >> breaking already broken code appear to have won the day. >> > > Again, why should a C implementation be rendered non-conforming [to some > future Standard] thusly? Because in most cases such code is an accident waiting to happen. It was amusing to see how much cruft was removed from the OpenSolaris code base when the default action of the native C compiler changed to use read only literals! Although it's a specific example, it does illustrate a more general point - assuming writeable literals is non-portable. All those code changes were also required to get the code to compile with gcc. > In a "bare metal" environment, one might very well wish to overwrite > their string literals' storage, no? The "bare metal" implementation > might need to define such action as being appropriate. Most "bare metal" environments I have used place literals in a read only segment, RAM is usually a more precious (and expensive) resource than ROM/FLASH on embedded systems. > By using "proper" static arrays, we lose out on the "shared storage" > benefit. Writing for bare metal, hopefully one knows what one is doing. Embedded tools usually have a rich set of pragmas and link options to specify where various types of object live. It's nigh on impossible to write a pure standard C embedded application. > Is this example silly? No, but it is easily worked round, tool sets with a C++ compiler already have to. -- Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-06-22 17:23 -0700 |
| Message-ID | <ln39j1gzu0.fsf@nuthaus.mib.org> |
| In reply to | #6673 |
Shao Miller <sha0.miller@gmail.com> writes:
> On 6/22/2011 2:56 PM, Ian Collins wrote:
>> On 06/22/11 10:25 PM, James Kuyper wrote:
[...]
>> The existing code problem was a acknowledged when C++ changed the type
>> of string literals. Compilers may choose not to issues a diagnostic for
>> this case. Now we have had over a decade to fix the smelly code, I
>> believe a diagnostic is now required by the new C++ standard.
>>
>> C could and should have done the same, but as usual those worried about
>> breaking already broken code appear to have won the day.
>>
>
> Again, why should a C implementation be rendered non-conforming [to some
> future Standard] thusly?
>
> In a "bare metal" environment, one might very well wish to overwrite
> their string literals' storage, no? The "bare metal" implementation
> might need to define such action as being appropriate.
>
> By using "proper" static arrays, we lose out on the "shared storage"
> benefit. Writing for bare metal, hopefully one knows what one is doing.
>
> Is this example silly?
If there's a need for a "bare metal" environment to be able to modify
string literals, that can be provided as an extension. Any code that
currently takes advantage of that ability already has undefined
behavior.
If such a feature were desirable, we could have an optional 'M' (for
modifiable) prefix for string literals, similar to the existing 'L'
prefix for wide string literals. For example, "hello" could be of type
const char[6], and M"hello" could be of type char[6]].
The fact that I've never heard of anyone implementing something like
this suggests (though not strongly) that there's no demand for it.
I suspect that the vast majority of code that attempts to modify
string literals does so as the result of bugs. A lot more code
uses string literals in contexts that don't treat them as const,
but doesn't actually try to modify them; for example:
void func(char *s) {
printf("In func(), s = \"%s\"\n");
}
...
func("hello");
In short, I think the issue is not that anyone wants to modify
string literals; it's that making them const would break existing
code that *doesn't* actually modify string literals.
(Stroustrup was able to do this in C++ because there was no existing
C++ code before he invented the language.)
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-06-23 12:54 +1200 |
| Message-ID | <96fh71FmtvU11@mid.individual.net> |
| In reply to | #6683 |
On 06/23/11 12:23 PM, Keith Thompson wrote:
>
> I suspect that the vast majority of code that attempts to modify
> string literals does so as the result of bugs. A lot more code
> uses string literals in contexts that don't treat them as const,
> but doesn't actually try to modify them; for example:
>
> void func(char *s) {
> printf("In func(), s = \"%s\"\n");
> }
>
> ...
>
> func("hello");
>
> In short, I think the issue is not that anyone wants to modify
> string literals; it's that making them const would break existing
> code that *doesn't* actually modify string literals.
>
> (Stroustrup was able to do this in C++ because there was no existing
> C++ code before he invented the language.)
No quite, the change came in with the 1998 C++ standard so there was
plenty of existing code. That's why there was a "special case" which
allows your example to pass without requiring a diagnostic.
--
Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-06-22 18:18 -0700 |
| Message-ID | <lntybhfir4.fsf@nuthaus.mib.org> |
| In reply to | #6687 |
Ian Collins <ian-news@hotmail.com> writes:
> On 06/23/11 12:23 PM, Keith Thompson wrote:
>> I suspect that the vast majority of code that attempts to modify
>> string literals does so as the result of bugs. A lot more code
>> uses string literals in contexts that don't treat them as const,
>> but doesn't actually try to modify them; for example:
>>
>> void func(char *s) {
>> printf("In func(), s = \"%s\"\n");
>> }
>>
>> ...
>>
>> func("hello");
>>
>> In short, I think the issue is not that anyone wants to modify
>> string literals; it's that making them const would break existing
>> code that *doesn't* actually modify string literals.
>>
>> (Stroustrup was able to do this in C++ because there was no existing
>> C++ code before he invented the language.)
>
> No quite, the change came in with the 1998 C++ standard so there was
> plenty of existing code. That's why there was a "special case" which
> allows your example to pass without requiring a diagnostic.
The change I was referring to was making string literals const.
I'm not familiar with the "special case"; I'll have to look into it
(elsewhere).
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-06-23 13:23 +1200 |
| Message-ID | <96fiscFmtvU12@mid.individual.net> |
| In reply to | #6689 |
On 06/23/11 01:18 PM, Keith Thompson wrote:
> Ian Collins<ian-news@hotmail.com> writes:
>> On 06/23/11 12:23 PM, Keith Thompson wrote:
>>> I suspect that the vast majority of code that attempts to modify
>>> string literals does so as the result of bugs. A lot more code
>>> uses string literals in contexts that don't treat them as const,
>>> but doesn't actually try to modify them; for example:
>>>
>>> void func(char *s) {
>>> printf("In func(), s = \"%s\"\n");
>>> }
>>>
>>> ...
>>>
>>> func("hello");
>>>
>>> In short, I think the issue is not that anyone wants to modify
>>> string literals; it's that making them const would break existing
>>> code that *doesn't* actually modify string literals.
>>>
>>> (Stroustrup was able to do this in C++ because there was no existing
>>> C++ code before he invented the language.)
>>
>> No quite, the change came in with the 1998 C++ standard so there was
>> plenty of existing code. That's why there was a "special case" which
>> allows your example to pass without requiring a diagnostic.
>
> The change I was referring to was making string literals const.
That was the change introduced by the standard. Prior to that, C++ had
the same rule as C. The change was a hot topic of discussion at the
ACCU conference held just after the standard was ratified.
--
Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2011-06-24 15:39 -0400 |
| Message-ID | <iu2p8p$ubl$1@dont-email.me> |
| In reply to | #6683 |
On 6/22/2011 20:23, Keith Thompson wrote:
> Shao Miller<sha0.miller@gmail.com> writes:
>> On 6/22/2011 2:56 PM, Ian Collins wrote:
>>> On 06/22/11 10:25 PM, James Kuyper wrote:
> [...]
>>> The existing code problem was a acknowledged when C++ changed the type
>>> of string literals. Compilers may choose not to issues a diagnostic for
>>> this case. Now we have had over a decade to fix the smelly code, I
>>> believe a diagnostic is now required by the new C++ standard.
>>>
>>> C could and should have done the same, but as usual those worried about
>>> breaking already broken code appear to have won the day.
>>>
>>
>> Again, why should a C implementation be rendered non-conforming [to some
>> future Standard] thusly?
>>
>> In a "bare metal" environment, one might very well wish to overwrite
>> their string literals' storage, no? The "bare metal" implementation
>> might need to define such action as being appropriate.
>>
>> By using "proper" static arrays, we lose out on the "shared storage"
>> benefit. Writing for bare metal, hopefully one knows what one is doing.
>>
>> Is this example silly?
>
> If there's a need for a "bare metal" environment to be able to modify
> string literals, that can be provided as an extension.
As in, a documented extension?
> Any code that
> currently takes advantage of that ability already has undefined
> behavior.
>
Exactly the nature of my question. If there is at least one real
program that depends on this "undefined behaviour" (use the Standard
definition, please :) ), then that program's source code might have to
be adjusted for future versions of an implementation, depending on how
that future implementation implements the extension.
> If such a feature were desirable, we could have an optional 'M' (for
> modifiable) prefix for string literals, similar to the existing 'L'
> prefix for wide string literals. For example, "hello" could be of type
> const char[6], and M"hello" could be of type char[6]].
>
An interesting idea! 'M()' could get close, perhaps.
#define M(string) ((char[]){string})
I guess we'd need 'ML', too?
> The fact that I've never heard of anyone implementing something like
> this suggests (though not strongly) that there's no demand for it.
>
Suppose you've a program loaded into memory via a serial line. Suppose
the program is loaded into writable memory (that seems pretty likely).
Suppose the program offers a CLI. Suppose a user can rename commands or
variables, or redefine preset scripts. Yes, all of these could be done
cleanly (in my opinion) via 'static' 'char[]'s, but it can be more
convenient for some people to simply type the string literal right into
some spot in the source code where it's used and forget about coming up
with a meaningful (and possibly redundant) identifier, i.e.
'csz_Hello__world___And_how_are_you__today_'
> I suspect that the vast majority of code that attempts to modify
> string literals does so as the result of bugs.
That seems probable to me, too.
> A lot more code
> uses string literals in contexts that don't treat them as const,
> but doesn't actually try to modify them; for example:
>
> void func(char *s) {
> printf("In func(), s = \"%s\"\n");
> }
>
> ...
>
> func("hello");
>
> In short, I think the issue is not that anyone wants to modify
> string literals;
For the right use case, I would.
> it's that making them const would break existing
> code that *doesn't* actually modify string literals.
>
> (Stroustrup was able to do this in C++ because there was no existing
> C++ code before he invented the language.)
>
Well doesn't 'const' "come from" C++, anyway?
And why isn't there a write-only counterpart, for symmetry, such as a
memory-mapped port that mustn't be read from?
And during very early development (and Usenet code examples), can it be
pleasant to avoid 'const' concerns altogether and then to analyze and
refine, gradually sprinkling 'const' in where appropriate? I don't
advocate this, but imagine that some folks might get "stuck" in
"analysis paralysis" if they had to think 'const'ness through at every
corner. I could be mistaken.
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-06-25 09:28 +1200 |
| Message-ID | <96kdsvFb9tU7@mid.individual.net> |
| In reply to | #6865 |
On 06/25/11 07:39 AM, Shao Miller wrote:
> On 6/22/2011 20:23, Keith Thompson wrote:
>
>> The fact that I've never heard of anyone implementing something like
>> this suggests (though not strongly) that there's no demand for it.
>>
>
> Suppose you've a program loaded into memory via a serial line. Suppose
> the program is loaded into writable memory (that seems pretty likely).
> Suppose the program offers a CLI. Suppose a user can rename commands or
> variables, or redefine preset scripts.
A recipe for disaster! What happens if a new name is linger than the old?
> Yes, all of these could be done
> cleanly (in my opinion) via 'static' 'char[]'s, but it can be more
> convenient for some people to simply type the string literal right into
> some spot in the source code where it's used and forget about coming up
> with a meaningful (and possibly redundant) identifier, i.e.
> 'csz_Hello__world___And_how_are_you__today_'
Yuck, what a contrived example! As you say, there is a method that does
not use undefined behaviour.
>> I suspect that the vast majority of code that attempts to modify
>> string literals does so as the result of bugs.
>
> That seems probable to me, too.
>
>> A lot more code
>> uses string literals in contexts that don't treat them as const,
>> but doesn't actually try to modify them; for example:
>>
>> void func(char *s) {
>> printf("In func(), s = \"%s\"\n");
>> }
>>
>> ...
>>
>> func("hello");
>>
>> In short, I think the issue is not that anyone wants to modify
>> string literals;
>
> For the right use case, I would.
>
>> it's that making them const would break existing
>> code that *doesn't* actually modify string literals.
>>
>> (Stroustrup was able to do this in C++ because there was no existing
>> C++ code before he invented the language.)
>>
>
> Well doesn't 'const' "come from" C++, anyway?
No, it's just used properly there!
> And why isn't there a write-only counterpart, for symmetry, such as a
> memory-mapped port that mustn't be read from?
That case isn't uncommon in embedded systems (watchdog reset being a
common example). However reading is generally harmless.
> And during very early development (and Usenet code examples), can it be
> pleasant to avoid 'const' concerns altogether and then to analyze and
> refine, gradually sprinkling 'const' in where appropriate? I don't
> advocate this, but imagine that some folks might get "stuck" in
> "analysis paralysis" if they had to think 'const'ness through at every
> corner. I could be mistaken.
Not really, if you don't know whether the function you are writing will
modify its arguments, you are big trouble!
--
Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-06-24 14:58 -0700 |
| Message-ID | <lnfwmydh7i.fsf@nuthaus.mib.org> |
| In reply to | #6887 |
Ian Collins <ian-news@hotmail.com> writes:
> On 06/25/11 07:39 AM, Shao Miller wrote:
[...]
>> Well doesn't 'const' "come from" C++, anyway?
>
> No, it's just used properly there!
See the ANSI C Rationale, at
<http://www.lysator.liu.se/c/rat/c5.html#3-5-3>:
The Committee has added to C two type qualifiers: const and
volatile. Individually and in combination they specify the
assumptions a compiler can and must make when accessing an
object through an lvalue.
The syntax and semantics of const were adapted from C++; the
concept itself has appeared in other languages. volatile is
an invention of the Committee; it follows the syntactic model
of const.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
Page 1 of 3 [1] 2 3 Next page →
Back to top | Article view | comp.lang.c
csiph-web