String literals and storage duration

L

lithiumcat

Hi,

I'm not yet very confident in my use of standard terminology, so
please be kind if I'm mis-calling something, I will do my best no to
make it again once pointed out.

I'm wondering what is the lifetime or a compile-time string constant,
I think that is what is called the storage duration of a string
litteral.

For example, let's say I've got a void foo(const char*) function, and
I'm calling it like this:
foo("simple string");
For how long can I use the pointer passed to foo? Let's say it stores
it somewhere, and another function, const char *bar(void) returns the
pointer passed to foo. Is that pointer still usable in a completely
different scope.

And I have the same questions with a call like this:
char *str = "simple string";
foo(str);

The last possibility I can think of is the following:
char str[] = "simple string";
foo(str);
That's the only one I think I know: str is an array with automatic
storage duration, and therefore the pointers that foo gets is valid as
long as we are in the scope of str. If str is declared like that in
the beginning of a function named "baz", a call to the previously said
bar() function would return a valid pointer until the function baz
exists. Or am I mistaken?


Thanks a lot for your help and your patience with me.
 
T

Tomás Ó hÉilidhe

I'm wondering what is the lifetime of a compile-time string constant,
I think that is what is called the storage duration of a string
litteral.


You can use it from the beginning of the program to the end of the
program, just as if it were a global object. Basically, in the context
of your program, it lives forever.

For example, let's say I've got a void foo(const char*) function, and
I'm calling it like this:
foo("simple string");
For how long can I use the pointer passed to foo?


For the entire program. It's as if you did the following:

char const str[] = "simple string"; /* Global object */

int main(void)
{
foo(str);
return 0;
}

Let's say it stores
it somewhere, and another function, const char *bar(void) returns the
pointer passed to foo. Is that pointer still usable in a completely
different scope.


Yes. Just pretend the string is a global object.

And I have the same questions with a call like this:
char *str = "simple string";
foo(str);


Again, "simple string" can be thought of as a global object that will
live for the duration of the entire program. Use it, abuse it, do
whatever you want to it. You can play around with its address of the
entirety of the program.

The last possibility I can think of is the following:
char str[] = "simple string";
foo(str);
That's the only one I think I know: str is an array with automatic
storage duration, and therefore the pointers that foo gets is valid as
long as we are in the scope of str. If str is declared like that in
the beginning of a function named "baz", a call to the previously said
bar() function would return a valid pointer until the function baz
exists. Or am I mistaken?


You're correct. Don't let the syntax of:

char str[] = "simple string";

fool you. That thing between the inverted commas is NOT a string
literal; it's just a pretty way of writing:

char str[] = { 's', 'i', 'm', 'p' ....

And as you know, automatic objects get destroyed when you exit the
block and so any pointers to them become invalid.
 
L

lithiumcat

Ok so string literals have static storage duration. Thanks a lot for
clarifying that.

The part of "ISO/IEC 9899:TC3" I found regarding this is 6.2.4, which
seems to cover only objects associated to an identifier, and in my
examples string literals were not associated with anything, there were
only pointers to it with their own storage durations.
 
R

Robert Gamble

Ok so string literals have static storage duration. Thanks a lot for
clarifying that.

The part of "ISO/IEC 9899:TC3" I found regarding this is 6.2.4, which
seems to cover only objects associated to an identifier, and in my
examples string literals were not associated with anything, there were
only pointers to it with their own storage durations.

§6.4.5p5:

"In translation phase 7, a byte or code of value zero is appended to
each multibyte character sequence that results from a string literal
or literals. The multibyte character sequence is then used to
initialize an array of static storage duration and length just
sufficient to contain the sequence. For character string literals, the
array elements have type char, and are initialized with the individual
bytes of the multibyte character sequence; for wide string literals,
the array elements have type wchar_t, and are initialized with the
sequence of wide characters corresponding to the multibyte character
sequence, as defined by the mbstowcs function with an implementation-
defined current locale."
 
P

Peter Nilsson

Richard said:
(e-mail address removed) said:
...
char str[] = "simple string";
foo(str);

...The literal is used only as a place from which
to copy into the array.

Depends what you mean by copy.

The standard says the array elements are initialised
by the string literal. That needn't be the same as
a byte copy.

Consider...

signed char str[] = "\0xFE";

If plain char is unsigned, then the value of str[0] is...
(signed char) 0xFE, which need not be the same
value as... * (signed char *) &"\xFE"[0].
 
C

Chris Torek

Ok so string literals have static storage duration.

Technically, it is "arrays created by string literals", not the
string literals themselves. The string literals are strictly a
source-code construct. If you are familiar with the way that
compilers discard[%] local variable names (replacing them with
things like registers or stack-frame offsets) during compilation,
think of string literals in the same way: the compiler turns the
string literal into an appropriate "runtime" thing, and if that
runtime thing is an array of "char" (or wchar_t for L"foo") -- as
it is in most cases -- the array has static duration.

[% Exception to the "discard" rule: the compiler may record the
name -> register or name -> stack-offset mapping for a debugger.
Depending on how "smart" the compiler and debugger are, this
debug-info can become quite complicated, e.g., if a local variable's
lifetime is altered and/or it is sometimes kept in a register, but
sometimes in memory, for instance.]
 

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,982
Messages
2,570,186
Members
46,740
Latest member
JudsonFrie

Latest Threads

Top