Question about string constants, para 5.5 K&R

G

Guest

From the book
"There is an important difference between these definitions:

char amessage[]="now is the time";
char *pmessage ="now is the time";

snip

On the other hand, pmessage is a pointer, initialized to point a
string const; the pointer may be modified to point elsewhere, but the
result is undefined if you try to modify the string constants."



1) So the statement
*pmessage='b';
may not change 'now' to 'bow'??????
but the statement
amessage[0]='b';

is always guaranteed to change 'now' to 'bow'

Please note there is no mention of the const qualifier in the text. I
understand amessage is a constant pointer to a char, but really don't
understand why pmessage is pointer to a constant char, especially if I
decide to use pmessage as an auto variable (implying that the stack in
RAM (read/write storage) will hold "now is the time"
 
I

Ian Collins

nospam said:
From the book
"There is an important difference between these definitions:

char amessage[]="now is the time";
char *pmessage ="now is the time";

snip

On the other hand, pmessage is a pointer, initialized to point a
string const; the pointer may be modified to point elsewhere, but the
result is undefined if you try to modify the string constants."

1) So the statement
*pmessage='b';
may not change 'now' to 'bow'??????

Or it might make your toilet explode, it is undefined behaviour.
but the statement
amessage[0]='b';

is always guaranteed to change 'now' to 'bow'
Yes, because amessage is a (zero terminated) automatic array of char.
Please note there is no mention of the const qualifier in the text. I
understand amessage is a constant pointer to a char, but really don't
understand why pmessage is pointer to a constant char, especially if I
decide to use pmessage as an auto variable (implying that the stack in
RAM (read/write storage) will hold "now is the time"

pmesssage may be an automatic variable, but what it points to is a
string literal, the location of which is an implementation detail.

Unfortunately, the C99 committee missed the opportunity to fix the use
of char* with string literals, unlike the C++ committee who did.
 
R

Richard Heathfield

nospam said:

Please note there is no mention of the const qualifier in the text. I
understand amessage is a constant pointer to a char, but really don't
understand why pmessage is pointer to a constant char, especially if I
decide to use pmessage as an auto variable (implying that the stack in
RAM (read/write storage) will hold "now is the time"

Who says it has to be RAM? Implementations are allowed to put string
literals in read-only memory (ROM). They might do that, and they might not
- you never can tell, with implementations.
 
G

gw7rib

nospam said:
From the book
"There is an important difference between these definitions:
char amessage[]="now is the time";
char *pmessage ="now is the time";

On the other hand, pmessage is a pointer, initialized to point a
string const; the pointer may be modified to point elsewhere, but the
result is undefined if you try to modify the string constants."
1) So the statement
*pmessage='b';
may not change 'now' to 'bow'??????
Or it might make your toilet explode, it is undefined behaviour.

I've seen this problem raised a number of times, and I have a
question. I appreciate that the standard says that this is undefined
behaviour. So according to the standard anything *could* happen. My
question regards what *actually* happens on real systems.

People have said that the string may be put into ROM, so the string
doesn't actually get changed. Fair enough, but presumably it tends not
to happen on a PC. The symptom most people seem to report when asking
about this problem is that their system segfaults. Why does/might this
happen? The standard requires that the string be readable properly, so
why do things go horribly wrong when you try to write to it? Surely if
a PC can find a memory address to read from it it can write to it?
 
J

Jens Thoms Toerring

nospam said:
From the book
"There is an important difference between these definitions:
char amessage[]="now is the time";
char *pmessage ="now is the time";

On the other hand, pmessage is a pointer, initialized to point a
string const; the pointer may be modified to point elsewhere, but the
result is undefined if you try to modify the string constants."
1) So the statement
*pmessage='b';
may not change 'now' to 'bow'??????
Or it might make your toilet explode, it is undefined behaviour.
I've seen this problem raised a number of times, and I have a
question. I appreciate that the standard says that this is undefined
behaviour. So according to the standard anything *could* happen. My
question regards what *actually* happens on real systems.
People have said that the string may be put into ROM, so the string
doesn't actually get changed. Fair enough, but presumably it tends not
to happen on a PC. The symptom most people seem to report when asking
about this problem is that their system segfaults. Why does/might this
happen? The standard requires that the string be readable properly, so
why do things go horribly wrong when you try to write to it? Surely if
a PC can find a memory address to read from it it can write to it?

Because making something non-writable can not only be achieved by
putting it into a ROM. Some systems allow to mark certain memory
ranges as read-only which gets enforced by the hardware by "throw-
ing" what finally ends up as a segmentation fault if one tries to
write there (the same is probably going to happen when you try to
write over the programs code which also typically isn't in ROM).
But some compilers allow you to request that literal strings get
stored in writable memory, e.g. gcc has a '-fwritable-strings'
option for that.
Regards, Jens
 
C

CBFalconer

.... snip ...


I've seen this problem raised a number of times, and I have a
question. I appreciate that the standard says that this is undefined
behaviour. So according to the standard anything *could* happen. My
question regards what *actually* happens on real systems.

Please enumerate ALL real systems, with links to their source
code. After that we can discuss my fee for investigating them.
 
J

Joe Wright

nospam said:
From the book
"There is an important difference between these definitions:

char amessage[]="now is the time";
char *pmessage ="now is the time";

snip

On the other hand, pmessage is a pointer, initialized to point a
string const; the pointer may be modified to point elsewhere, but the
result is undefined if you try to modify the string constants."
Yes.


1) So the statement
*pmessage='b';
may not change 'now' to 'bow'??????
but the statement
amessage[0]='b';

is always guaranteed to change 'now' to 'bow'
Yes.

Please note there is no mention of the const qualifier in the text. I
understand amessage is a constant pointer to a char, but really don't
understand why pmessage is pointer to a constant char, especially if I
decide to use pmessage as an auto variable (implying that the stack in
RAM (read/write storage) will hold "now is the time"

None of this has anything to do with the 'const' qualifier. The
expression "now is the time" is a constant string in presumably
read-only memory. In the case of..

char *pmessage = "now is the time";

...pmessage is an auto variable pointing to a constant string which you
cannot write to.

char amessage[] = "now is the time";

...is another case. amessage is an array which you own and the constant
string is assigned (copied) to it. You may do anything to amessage you
please.
 
G

Guest

nospam said:
From the book
"There is an important difference between these definitions:
char amessage[]="now is the time";
char *pmessage ="now is the time";

On the other hand, pmessage is a pointer, initialized to point a
string const; the pointer may be modified to point elsewhere, but the
result is undefined if you try to modify the string constants."
1) So the statement
*pmessage='b';
may not change 'now' to 'bow'??????
Or it might make your toilet explode, it is undefined behaviour.

I've seen this problem raised a number of times, and I have a
question. I appreciate that the standard says that this is undefined
behaviour. So according to the standard anything *could* happen. My
question regards what *actually* happens on real systems.

char *p = "Hello, world!";
strcpy(p, "Goodbye!");
puts("Hello, world!");

String literals may share storage, and commonly do. The call to strcpy
would also cause the call to puts to print out a different string (if
it didn't already cause more direct problems).
People have said that the string may be put into ROM, so the string
doesn't actually get changed. Fair enough, but presumably it tends not
to happen on a PC. The symptom most people seem to report when asking
about this problem is that their system segfaults. Why does/might this
happen? The standard requires that the string be readable properly, so
why do things go horribly wrong when you try to write to it? Surely if
a PC can find a memory address to read from it it can write to it?

Several modern and even older system provide forms of memory
protection, where blocks of memory can be read from but not written
to, or vice versa.
 
S

santosh

nospam said:
From the book
"There is an important difference between these definitions:
char amessage[]="now is the time";
char *pmessage ="now is the time";

On the other hand, pmessage is a pointer, initialized to point a
string const; the pointer may be modified to point elsewhere, but the
result is undefined if you try to modify the string constants."
1) So the statement
*pmessage='b';
may not change 'now' to 'bow'??????
Or it might make your toilet explode, it is undefined behaviour.

I've seen this problem raised a number of times, and I have a
question. I appreciate that the standard says that this is undefined
behaviour. So according to the standard anything *could* happen. My
question regards what *actually* happens on real systems.

People have said that the string may be put into ROM, so the string
doesn't actually get changed. Fair enough, but presumably it tends not
to happen on a PC. The symptom most people seem to report when asking
about this problem is that their system segfaults. Why does/might this
happen? The standard requires that the string be readable properly, so
why do things go horribly wrong when you try to write to it? Surely if
a PC can find a memory address to read from it it can write to it?

Most modern processors provide some form of memory management, where
blocks of memory can be defined as readonly etc. Attempting to write
to such addresses cause an exception to be raised, which most often
causes the OS to abort the program. Some exceptions can be caught and
dealt with, though most simple programs don't do so.
 
G

Guest

nospam said:
From the book
"There is an important difference between these definitions:

char amessage[]="now is the time";
char *pmessage ="now is the time";

snip

On the other hand, pmessage is a pointer, initialized to point a
string const; the pointer may be modified to point elsewhere, but the
result is undefined if you try to modify the string constants."
Yes.


1) So the statement
*pmessage='b';
may not change 'now' to 'bow'??????
but the statement
amessage[0]='b';

is always guaranteed to change 'now' to 'bow'
Yes.

Please note there is no mention of the const qualifier in the text. I
understand amessage is a constant pointer to a char, but really don't
understand why pmessage is pointer to a constant char, especially if I
decide to use pmessage as an auto variable (implying that the stack in
RAM (read/write storage) will hold "now is the time"

None of this has anything to do with the 'const' qualifier. The
expression "now is the time" is a constant string in presumably
read-only memory. In the case of..

char *pmessage = "now is the time";

..pmessage is an auto variable pointing to a constant string which you
cannot write to.

char amessage[] = "now is the time";

..is another case. amessage is an array which you own and the constant
string is assigned (copied) to it. You may do anything to amessage you
please.

Shouldn't a good compiler complain that that pmessage points to a
const char, but pmessage is not declared as such?
 
R

Richard Heathfield

nospam said:
On Sun, 28 Jan 2007 13:10:13 -0500, Joe Wright wrote:
char *pmessage = "now is the time";

..pmessage is an auto variable pointing to a constant string which you
cannot write to.

char amessage[] = "now is the time";

..is another case. amessage is an array which you own and the constant
string is assigned (copied) to it. You may do anything to amessage you
please.

Shouldn't a good compiler complain that that pmessage points to a
const char, but pmessage is not declared as such?

You'd think so, wouldn't you? But unfortunately pmessage does *not* point to
a const char. It merely points to a char you're not allowed to change!

const char *pmessage = "now is the time";

will indeed prevent you from writing through pmessage, at least accidentally
- but the const modifier is not actually required by the language, because
"now is the time", although a constant, is not const! Personally, I think
it ought to be, but that probably isn't going to change any time soon.
 
R

Richard Bos

nospam said:
nospam said:
From the book
"There is an important difference between these definitions:

char amessage[]="now is the time";
char *pmessage ="now is the time";

snip

On the other hand, pmessage is a pointer, initialized to point a
string const; the pointer may be modified to point elsewhere, but the
result is undefined if you try to modify the string constants."
Yes.


1) So the statement
*pmessage='b';
may not change 'now' to 'bow'??????
but the statement
amessage[0]='b';

is always guaranteed to change 'now' to 'bow'
Yes.

Please note there is no mention of the const qualifier in the text. I
understand amessage is a constant pointer to a char, but really don't
understand why pmessage is pointer to a constant char, especially if I
decide to use pmessage as an auto variable (implying that the stack in
RAM (read/write storage) will hold "now is the time"

None of this has anything to do with the 'const' qualifier. The
expression "now is the time" is a constant string in presumably
read-only memory. In the case of..

char *pmessage = "now is the time";

..pmessage is an auto variable pointing to a constant string which you
cannot write to.

char amessage[] = "now is the time";

..is another case. amessage is an array which you own and the constant
string is assigned (copied) to it. You may do anything to amessage you
please.

Shouldn't a good compiler complain that that pmessage points to a
const char, but pmessage is not declared as such?

No, because a string literal does not consist of const chars, but of
chars (mainly for hysterical raisins).

Richard
 
K

Keith Thompson

nospam said:
On Sun, 28 Jan 2007 13:10:13 -0500, Joe Wright
char *pmessage = "now is the time";
[...]
Shouldn't a good compiler complain that that pmessage points to a
const char, but pmessage is not declared as such?

pmessage doesn't point to a const char, it points to (the first
character of) a string literal. For historical reasons, string
literals are not const. (Attempting to modify a string literal
invokes undefined behavior, but only because the standard explicitly
says so.)
 
C

CBFalconer

nospam said:
.... snip ..
char *pmessage = "now is the time";

..pmessage is an auto variable pointing to a constant string
which you cannot write to.

char amessage[] = "now is the time";

..is another case. amessage is an array which you own and the
constant string is assigned (copied) to it. You may do anything
to amessage you please.

Shouldn't a good compiler complain that that pmessage points to a
const char, but pmessage is not declared as such?

Just use gcc with -Wwrite-strings. Along with -W -Wall -ansi
-pedantic, of course.
 
B

Barry Schwarz

From the book
"There is an important difference between these definitions:

char amessage[]="now is the time";
char *pmessage ="now is the time";

snip

On the other hand, pmessage is a pointer, initialized to point a
string const; the pointer may be modified to point elsewhere, but the
result is undefined if you try to modify the string constants."



1) So the statement
*pmessage='b';
may not change 'now' to 'bow'??????
but the statement
amessage[0]='b';

is always guaranteed to change 'now' to 'bow'

Please note there is no mention of the const qualifier in the text. I
understand amessage is a constant pointer to a char, but really don't

amessage is not a constant pointer to char. It is not a pointer at
all. It is an array. While they share certain properties (with
respect to the [] and * operators) and while expressions of type array
of T frequently EVALUATE to values with type pointer to T, they are
still very distinct. Pointers are scalar; arrays are aggregates.
Define an array and a pointer and print the sizeof each.
understand why pmessage is pointer to a constant char, especially if I

pmessage is not a pointer to constant char because a lot of code was
written before the const qualifier was added to the language. A lot
of that contained definitions of the form
char *ptr = "some literal string";

If the literal string were const, a new compiler would be required to
issue a diagnostic for attempting to assign the address of a const to
a pointer not of type pointer to const. The standards committee is
sensitive to the economic impact of its decisions and the amount of
code that would become broken was large enough to warrant
consideration. As a compromise, the committee decided to make the
attempt to modify the string literal undefined.
decide to use pmessage as an auto variable (implying that the stack in
RAM (read/write storage) will hold "now is the time"

auto does not imply stack at all. The standard doesn't even discuss
stack) auto is simply a storage duration.

pmessage will not hold "now is the time". It will hold the address of
the first character of the that literal.


Remove del for email
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top