[comp.lang.c] Do string constants persist out of scope?

adamk@mit-amt.MEDIA.MIT.EDU (Adam Kao) (01/12/90)

If I define a string constant in a procedure and then pass it back
out, does the pointer I get remain valid?  I'm confused because
strings are really char pointers.  I tried it in a test program and it
worked, but I'm a little worried it might be accidental.  I guess what
I'm really asking is whether the compiler permanently allocates memory
for all the string constants in the whole program.

Thanks in advance,

Adam

chris@mimsy.umd.edu (Chris Torek) (01/15/90)

In article <1380@mit-amt.MEDIA.MIT.EDU> adamk@mit-amt.MEDIA.MIT.EDU
(Adam Kao) writes:
>If I define a string constant in a procedure and then pass it back
>out, does the pointer I get remain valid?  I'm confused because
>strings are really char pointers.

(The specific answer is in `d.' below, for the impatient.)  Strings
are not char pointers, although they can be found via char pointers.
String constants---that is, things written as

	"text"

---are objects with:

a. Type.  This is the first question to ask about any object
   or value in C.  Nothing else can be decided without this
   information.

   The type of a string constant is `array N of char', where N is one
   more than the number of characters in the string.  In ANSI C, the
   `char's in the array must not be modified by the programmer;
   nonetheless, the type is not `array N of const char'.  (The reason
   for this has to do with some aspects of type compatibility that
   are, in my opinion, bogus.)

b. Value.  (This is the next question, once you have the type.)

   The value of a string constant is the sequence of characters
   enclosed in quotes (backslash escapes having been interpreted
   in the process), followed by a character with ordinal value
   zero (often called `NUL', or `the null character': do not
   confuse this with `NULL').

c. Scope.  An object with a name has a scope (one of block, file,
   or `external' [meaning global]); this tells you how far away
   you can get before the name becomes invisible.  The keyword
   `static' in a declaration can change the default scope of a name.

   A string constant has no name, hence no scope.

d. Storage duration.  An object has some location in memory, and
   that memory has a lifetime.  There are two durations, called
   `automatic' and `static'.  Note that this `static' differs from
   the C keyword `static'.  Only objects with block scope may have
   automatic duration: everything else has static duration.  Objects
   with block scope have automatic duration unless they are declared
   with the keyword `static'.

   A string constant has no scope, hence it has static duration.

Thus, a string constant is an unnamed object of type `array N of char',
with the obvious value, that has no scope and has static duration.  It
is therefore safe to obtain a pointer to any of the `char's making up
the array, and follow that pointer at any time later during the program.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@cs.umd.edu	Path:	uunet!mimsy!chris

davidsen@sixhub.UUCP (Wm E. Davidsen Jr) (01/16/90)

In article <1380@mit-amt.MEDIA.MIT.EDU> adamk@media-lab.media.mit.edu.UUCP (Adam Kao) writes:
| 
| If I define a string constant in a procedure and then pass it back
| out, does the pointer I get remain valid?  I'm confused because
| strings are really char pointers.  

  The answer to your question is yes, a string constant is permanently
allocated. However, a string is not "really a char pointer" the way you
mean it, the quote notation denotes a permanently allocated character
array, null terminated, having an rvalue of the address of the first
character. I don't have a standard here, but that's close.

  One of the major differences between K&R and ANSI is that strings are
constants. In K&R you could do some bizarre things by modifying the
value of strings. In ANSI that is either forbidden or not guaranteed to
work (I believe the latter) and the compiler is allowed to have one
address for all constants having the same value. In K&R it says all
strings must be separate arrays.

  In the case:
	foo("abc", "abc");
K&R requires there to be two strings, ANSI allows one. I don't believe
it requires only one, but you will have to look that up if you care.
-- 
	bill davidsen - sysop *IX BBS and Public Access UNIX
davidsen@sixhub.uucp		...!uunet!crdgw1!sixhub!davidsen

"Getting old is bad, but it beats the hell out of the alternative" -anon