By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,305 Members | 1,588 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,305 IT Pros & Developers. It's quick & easy.

Read-only string

P: n/a
why the following string, 'str' is read-only?

char *str = "test string";

anyhow 'str' needs to be in memory. do you think, making 'str' red-only
would gain performance? or, it is right?

Jun 21 '06 #1
Share this Question
Share on Google+
24 Replies


P: n/a

v4vijayakumar wrote:
why the following string, 'str' is read-only?

char *str = "test string";

anyhow 'str' needs to be in memory. do you think, making 'str' red-only
would gain performance? or, it is right?


Character pointer `str` is /not/ read-only. You are free to assign any
other character pointer value to it. What /is/ read-only is the string
literal somewhere in memory to which `str` points.

One reason for this is that it enables embedded applications to put the
string literal into (physically) read-only memory. This may or may not
gain performance, but certainly saves RAM which in these systems tends
to command a price premium.

Jun 21 '06 #2

P: n/a
v4vijayakumar wrote:
why the following string, 'str' is read-only?
Because the C standard says so.
(well, it says it's undefined behavior to modify a string
literal) char *str = "test string";

anyhow 'str' needs to be in memory. do you think, making 'str' red-only str is not the same thing as "test string", str can be modified :-)
would gain performance? or, it is right?

Jun 21 '06 #3

P: n/a
Le 21-06-2006, v4vijayakumar <v4***********@yahoo.com> a écrit*:
why the following string, 'str' is read-only?

char *str = "test string";


Because that is the way the langage is defined ?
You could wonder why the langage is designed this way.
I was not there, but my few knoledges in compilation let
me assume that, for some compiler, it was easier to do
so (it allow to store it in read-only memory).

Marc Boyer
Jun 21 '06 #4

P: n/a


Vladimir Oka wrote:
v4vijayakumar wrote:
why the following string, 'str' is read-only?

char *str = "test string";

anyhow 'str' needs to be in memory. do you think, making 'str' red-only
would gain performance? or, it is right?


Character pointer `str` is /not/ read-only. You are free to assign any
other character pointer value to it. What /is/ read-only is the string
literal somewhere in memory to which `str` points.

One reason for this is that it enables embedded applications to put the
string literal into (physically) read-only memory. This may or may not
gain performance, but certainly saves RAM which in these systems tends
to command a price premium.

saving RAM?! anyhow still, you have to have these 12 bytes in RAM.

Jun 21 '06 #5

P: n/a


Marc Boyer wrote:
Le 21-06-2006, v4vijayakumar <v4***********@yahoo.com> a écrit :
why the following string, 'str' is read-only?

char *str = "test string";


Because that is the way the langage is defined ?
You could wonder why the langage is designed this way.
I was not there, but my few knoledges in compilation let
me assume that, for some compiler, it was easier to do
so (it allow to store it in read-only memory).

Marc Boyer

shouldn't it be the other way? it should be easier to programmers.

Jun 21 '06 #6

P: n/a
Le 21-06-2006, v4vijayakumar <v4***********@yahoo.com> a écrit*:
Marc Boyer wrote:
Le 21-06-2006, v4vijayakumar <v4***********@yahoo.com> a écrit :
> why the following string, 'str' is read-only?
>
> char *str = "test string";


Because that is the way the langage is defined ?
You could wonder why the langage is designed this way.
I was not there, but my few knoledges in compilation let
me assume that, for some compiler, it was easier to do
so (it allow to store it in read-only memory).


shouldn't it be the other way? it should be easier to programmers.


You could not expect C to be an 'universal' langage,
to find a C compiler for every platform *and* to require
too many things from the compiler.
So, yes, the C langage does not requires behaviors
that would be too hard/costly to implement (like a stop
of the program when dereferencing null pointer for
example, or out-of-bound array acces).

Marc Boyer
Jun 21 '06 #7

P: n/a
"v4vijayakumar" <v4***********@yahoo.com> wrote:
Vladimir Oka wrote:
v4vijayakumar wrote:
why the following string, 'str' is read-only?

char *str = "test string";

anyhow 'str' needs to be in memory. do you think, making 'str' red-only
would gain performance? or, it is right?
Character pointer `str` is /not/ read-only. You are free to assign any
other character pointer value to it. What /is/ read-only is the string
literal somewhere in memory to which `str` points.

One reason for this is that it enables embedded applications to put the
string literal into (physically) read-only memory. This may or may not
gain performance, but certainly saves RAM which in these systems tends
to command a price premium.


saving RAM?!


In embedded devices, yes, why not? In large programs on a PC, yes, why
not, if the string isn't "test string" but a 2000-entry array of
200-character strings?
anyhow still, you have to have these 12 bytes in RAM.


Says who? You put them in ROM, of course. ROM is often cheaper than RAM.
In "normal" programs, you can put them in the executable image, save
some superfluous string copying, and eliminate duplicates.

Richard
Jun 21 '06 #8

P: n/a
v4vijayakumar schrieb:

Vladimir Oka wrote:
v4vijayakumar wrote:
why the following string, 'str' is read-only?

char *str = "test string";

anyhow 'str' needs to be in memory. do you think, making 'str' red-only
would gain performance? or, it is right?

Character pointer `str` is /not/ read-only. You are free to assign any
other character pointer value to it. What /is/ read-only is the string
literal somewhere in memory to which `str` points.

One reason for this is that it enables embedded applications to put the
string literal into (physically) read-only memory. This may or may not
gain performance, but certainly saves RAM which in these systems tends
to command a price premium.

saving RAM?! anyhow still, you have to have these 12 bytes in RAM.


No, they can safely be placed into ROM, as the compiler can assume that
you will never modify the string literal. If you do so, you invoke
undefined behaviour, so the compiler is not responsible for this. If you
want a modifiable string, use the string literal as an initializer for
an array:

char str[] = "test string";

--
Marc Thrun
http://www.tekwarrior.de/
Jun 21 '06 #9

P: n/a
"v4vijayakumar" <v4***********@yahoo.com> wrote:
Marc Boyer wrote:
Le 21-06-2006, v4vijayakumar <v4***********@yahoo.com> a =E9crit :
why the following string, 'str' is read-only?

char *str = "test string";


Because that is the way the langage is defined ?
You could wonder why the langage is designed this way.
I was not there, but my few knoledges in compilation let
me assume that, for some compiler, it was easier to do
so (it allow to store it in read-only memory).


shouldn't it be the other way? it should be easier to programmers.


Why would it be easier for programmers? You can get the behaviour you
want using

char str[] = "test string";

and the efficient behaviour using

char *str = "test string";

Choice is good. Catering to stupid hack programmers is not good.

Richard
Jun 21 '06 #10

P: n/a

v4vijayakumar wrote:
Vladimir Oka wrote:
v4vijayakumar wrote:
why the following string, 'str' is read-only?

char *str = "test string";

anyhow 'str' needs to be in memory. do you think, making 'str' red-only
would gain performance? or, it is right?
Character pointer `str` is /not/ read-only. You are free to assign any
other character pointer value to it. What /is/ read-only is the string
literal somewhere in memory to which `str` points.

One reason for this is that it enables embedded applications to put the
string literal into (physically) read-only memory. This may or may not
gain performance, but certainly saves RAM which in these systems tends
to command a price premium.

saving RAM?!


RAM in your mobile phone ("cell" if you're on the other side of the
pond), to give one example, can command a price premium compared to
other types of memory used in it (mainly Flash). Being generally
faster, it can also be better used for time critical task (reading
constant strings is rarely such a task).

The fact that PC RAM and HDD space is (comapratively) cheap these days
is irrelevant to that particular market segment. Don't be blinded by
the obvious.
anyhow still, you have to have these 12 bytes in RAM.


Why, if you care to explain?

Yes, if you want to modify them, but then you're going about it the
wrong way. At least in C.

Jun 21 '06 #11

P: n/a

v4vijayakumar wrote:
Marc Boyer wrote:
Le 21-06-2006, v4vijayakumar <v4***********@yahoo.com> a écrit :
why the following string, 'str' is read-only?

char *str = "test string";


Because that is the way the langage is defined ?
You could wonder why the langage is designed this way.
I was not there, but my few knoledges in compilation let
me assume that, for some compiler, it was easier to do
so (it allow to store it in read-only memory).

Marc Boyer

shouldn't it be the other way? it should be easier to programmers.


But it is! It makes it easy for me to create cost/performance efficient
designs.

It also makes it easy for you, if you care to study language enough to
come across use of character arrays:

char str[] = "hello, world";

Jun 21 '06 #12

P: n/a
v4vijayakumar wrote:

Vladimir Oka wrote:
v4vijayakumar wrote:
why the following string, 'str' is read-only?

char *str = "test string";

anyhow 'str' needs to be in memory. do you think, making 'str' red-only
would gain performance? or, it is right?

Character pointer `str` is /not/ read-only. You are free to assign any
other character pointer value to it. What /is/ read-only is the string
literal somewhere in memory to which `str` points.

One reason for this is that it enables embedded applications to put the
string literal into (physically) read-only memory. This may or may not
gain performance, but certainly saves RAM which in these systems tends
to command a price premium.

saving RAM?! anyhow still, you have to have these 12 bytes in RAM.


Imagine an application with a lot of strings (my linux shell /bin/bash
seems to have almost 50KiB of text!).
Placing these strings in a read only "segment" can allow OSs to share
that part among multiple running instances of the application.
And it allows merging of strings too, ("World" and "Hello World" might
need just a 12 bytes of storage for those 2 strings + the pointers to
them) save a bit here and there , it might add up.

Jun 21 '06 #13

P: n/a
Vladimir Oka wrote:

v4vijayakumar wrote:

[...]
> char *str = "test string";
[...] shouldn't it be the other way? it should be easier to programmers.


But it is! It makes it easy for me to create cost/performance efficient
designs.

It also makes it easy for you, if you care to study language enough to
come across use of character arrays:

char str[] = "hello, world";


And things like this can lay in hiding in a program for years, or
even decades. Literally!

I had written code, back in the early 1980's, which included the
equivalent of:

char *filename = "foo.xxx";

...

strcpy(filename+4,"bar");

This "worked" until sometime in the 1990's, when the program was
ported to a system which actually did place "foo.xxx" into a read-
only memory segment. (Note that it was still in RAM. It's just
that the hardware and O/S supported marking some pages of memory
as "read-only data".)

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>
Jun 21 '06 #14

P: n/a
"Nils O. Selåsdal" wrote:
[...]
And it allows merging of strings too, ("World" and "Hello World" might
need just a 12 bytes of storage for those 2 strings + the pointers to
them) save a bit here and there , it might add up.


I assume that it could also merge "Hello" and "Hello World", _if_ the
"Hello" were defined without the trailing nul?

Now, how does one define a pointer to 5 chars?

cdecl says:

cdecl> explain char (*foo)[5];
declare foo as pointer to array 5 of char

but gcc complaint on this:

char (*foo)[5] = "Hello";

with:

foo.c:1: warning: initialization from incompatible pointer type

At first, I thought that's because "Hello" is actually an array of 6
chars, but changing it to "1234" gives the same error.

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>

Jun 21 '06 #15

P: n/a
Kenneth Brody said:
"Nils O. Selåsdal" wrote:
[...]
And it allows merging of strings too, ("World" and "Hello World" might
need just a 12 bytes of storage for those 2 strings + the pointers to
them) save a bit here and there , it might add up.
I assume that it could also merge "Hello" and "Hello World", _if_ the
"Hello" were defined without the trailing nul?

Now, how does one define a pointer to 5 chars?

cdecl says:

cdecl> explain char (*foo)[5];
declare foo as pointer to array 5 of char


Yes.

but gcc complaint on this:

char (*foo)[5] = "Hello";


Yes, because char (*)[5] is not the same as char * (which is what you get
when you evaluate a char[6] such as "Hello").

This works, though:

char bar[5] = "Hello"; /* caveat - bar does not contain a string */
char (*foo)[5] = &bar;
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 21 '06 #16

P: n/a
On 2006-06-21, v4vijayakumar <v4***********@yahoo.com> wrote:
why the following string, 'str' is read-only?

char *str = "test string";

anyhow 'str' needs to be in memory. do you think, making 'str' red-only
would gain performance? or, it is right?


Well, being as the compiler is allowed to put "test string" wherever it
wants, it could elect to put it within the executable code.

Now, an OS will likely not allow programs to modify executable code,
because that will make it too easy to create viruses. Therefore,
strings store in executable code are not modifiable.
That should be enough of an example for you; for others, read the rest
of the thread.

--
Andrew Poelstra < http://www.wpsoftware.net/blog >
To email me, use "apoelstra" at the above address.
I know that area of town like the back of my head.
Jun 21 '06 #17

P: n/a
"v4vijayakumar" <v4***********@yahoo.com> writes:
Marc Boyer wrote:
Le 21-06-2006, v4vijayakumar <v4***********@yahoo.com> a écrit :
> why the following string, 'str' is read-only?
>
> char *str = "test string";


Because that is the way the langage is defined ?
You could wonder why the langage is designed this way.
I was not there, but my few knoledges in compilation let
me assume that, for some compiler, it was easier to do
so (it allow to store it in read-only memory).


shouldn't it be the other way? it should be easier to programmers.


Easier to do what?

If strings are writable, then this program:
========================================
#include <stdio.h>
#include <string.h>

static void print_string(char *s)
{
puts(s);
strcpy(s, "xxxxx");
}

int main(void)
{
int i;
for (i = 0; i < 2; i ++) {
print_string("Hello");
}
return 0;
}
========================================
will produce this output:
========================================
Hello
xxxxx
========================================

It's easy enough to do this if it's what you want. By preventing you
from modifying string literals, the implementation is, in a small way,
preventing you from shooting yourself in the foot.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jun 21 '06 #18

P: n/a
>Kenneth Brody said:
... but gcc complaint on this:
char (*foo)[5] = "Hello";

In article <jN********************@bt.com>
Richard Heathfield <in*****@invalid.invalid> wrote:Yes, because char (*)[5] is not the same as char * (which is what you get
when you evaluate a char[6] such as "Hello").

This works, though:

char bar[5] = "Hello"; /* caveat - bar does not contain a string */
char (*foo)[5] = &bar;


Note that you can also write:

char (*p0)[5] = &"1234";

If you want a non-string, you must either use the method Richard
Heathfield showed above, or the newfangled C99 compound-literals:

char (*p1)[5] = &(char []){'H', 'e', 'l', 'l', 'o'};
char (*p2)[5] = &(char [5]){"Hello"};

The size of the array can be omitted only in the initializer for
p1, in this case.

(Sure would be nice if C89 had allowed one to write "Hello\z"
to suppress the trailing \0, instead of making up a silly rule for
array initializers with specified sizes. :-) )
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Jun 21 '06 #19

P: n/a
On 21 Jun 2006 04:09:23 -0700, in comp.lang.c , "v4vijayakumar"
<v4***********@yahoo.com> wrote:
(of readonly data)
saving RAM?! anyhow still, you have to have these 12 bytes in RAM.


No, you could burn it into ROM or an EEPROM or whatever. This is in
fact what many embedded systems do. Consider the BIOS in your
computer.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Jun 21 '06 #20

P: n/a
Rk

Andrew Poelstra wrote:
Well, being as the compiler is allowed to put "test string" wherever it
wants, it could elect to put it within the executable code.


Directly not related to the main topic, but while we are at it I feel
like clarifying this question of mine. I and my friend the other day
were discussing, where "test string" would be stored. In which part of
the memory.
After going through few tutorials on internet, I concluded, if it is
local declaration, the "test string" should resides in STACK. If it is
global or static declaration then, it should reside in "HEAP". In case
we are not using "heap" (in embedded systems we do not), then I could
just say that it stays in RAM.
Now you said it could be in executable code, which was what my friend
guessed.
Could you please clarify.
Thanks.
======
Rk
I am logged in therefore I am.

Jun 22 '06 #21

P: n/a
Rk wrote:
Andrew Poelstra wrote:
Well, being as the compiler is allowed to put "test string" wherever it
wants, it could elect to put it within the executable code.
Directly not related to the main topic, but while we are at it I feel
like clarifying this question of mine. I and my friend the other day
were discussing, where "test string" would be stored. In which part of
the memory.
After going through few tutorials on internet, I concluded, if it is
local declaration, the "test string" should resides in STACK. If it is
global or static declaration then, it should reside in "HEAP". In case
we are not using "heap" (in embedded systems we do not), then I could
just say that it stays in RAM.


The compiler can put the string "test string" wherever it likes. All
that is required is that there is a single location, it has the
required contents, and so long as the program exists (or at least
has a reference to that location or a character within it) the
location exists too - "static storage".

Note that if the declaration

char *str = "test string";

is function-local, it's /str/ that's function-local, not "test string".
In particular it would generally be unsound to store the characters
"test string" [plus terminating 0] on /that function call's/ "stack
frame" (if the implementation has one).
Now you said it could be in executable code, which was what my friend
guessed.


Yes. It /could/ be. Or it /could/ be in some chunk consisting of all
the initialised data from the program. Or it /could/ be in a chunk
consisting of all the initialised and non-writeable data from the
program. Such chunks might be allocated from the same part of the
address space as the "heap" (if there is one) or the "stack" (ditto).

--
Chris "seeker" Dollin
"Life is full of mysteries. Consider this one of them." Sinclair, /Babylon 5/

Jun 22 '06 #22

P: n/a
Chris Dollin wrote:

Rk wrote:
Andrew Poelstra wrote:
Well, being as the compiler is allowed to put "test string" wherever it
wants, it could elect to put it within the executable code.
Directly not related to the main topic, but while we are at it I feel
like clarifying this question of mine. I and my friend the other day
were discussing, where "test string" would be stored. In which part of
the memory.
After going through few tutorials on internet, I concluded, if it is
local declaration, the "test string" should resides in STACK.
If it is global or static declaration then,
it should reside in "HEAP". In case
we are not using "heap"
(in embedded systems we do not), then I could
just say that it stays in RAM.


The compiler can put the string "test string" wherever it likes. All
that is required is that there is a single location,


That depends on what you mean by "single location".
("test string" == "test string") is not guaranteed to be true.

it has the
required contents, and so long as the program exists (or at least
has a reference to that location or a character within it) the
location exists too - "static storage".

Note that if the declaration

char *str = "test string";

is function-local, it's /str/ that's function-local,
not "test string".


Yes.
The return values of func1 and func2 are defined.
The return value of func3 is not defined.
char *func1(void)
{
char *str = "test string";
return str;
}

char *func2(void)
{
return "test string";
}

char *func3(void)
{
char str[] = "test string";
return str;
}

--
pete
Jun 22 '06 #23

P: n/a
pete wrote:
Chris Dollin wrote:

The compiler can put the string "test string" wherever it likes. All
that is required is that there is a single location,


That depends on what you mean by "single location".
("test string" == "test string") is not guaranteed to be true.


Indeed. But in

char *spoo(void) { return "fresh spoo"; }

each call of `spoo` returns the same value: that particular string
`fresh spoo` has only one location during the lifetime of the
program, which is what I was trying to say.

I agree that I hadn't said clearly what I meant.

--
Chris "mud, mud, glorious\\\\\\\\muddy mud" Dollin
"No-one here is exactly what he appears." G'kar, /Babylon 5/

Jun 22 '06 #24

P: n/a
Richard Heathfield wrote:

Kenneth Brody said:

[...]
I assume that it could also merge "Hello" and "Hello World", _if_ the
"Hello" were defined without the trailing nul?

Now, how does one define a pointer to 5 chars?

cdecl says:

cdecl> explain char (*foo)[5];
declare foo as pointer to array 5 of char


Yes.

but gcc complaint on this:

char (*foo)[5] = "Hello";


Yes, because char (*)[5] is not the same as char * (which is what you get
when you evaluate a char[6] such as "Hello").

This works, though:

char bar[5] = "Hello"; /* caveat - bar does not contain a string */
char (*foo)[5] = &bar;


True, but that won't allow the compiler to merge "Hello" with "Hello
World" (as it can with char *foo="World",*bar="Hello World"), which
is what I was wondering about.

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>
Jun 22 '06 #25

This discussion thread is closed

Replies have been disabled for this discussion.