[comp.lang.c] Are strings local?

rgr@m10ux.UUCP (Duke Robillard) (08/02/88)

I've got a question about string constants.  According to the first
edition of K&R, stuff of the form "this is a string" is static (page 181).
This means they are "local to a block" (definition of static--page 182).
Okay, so does this mean that you can't do this:

	char *some_function()
	{
	  char *ptr;
	  ptr= "string";
	  return(ptr);
	}

It seems to me that "string" would only be defined inside some_function.
Is that right, or am I missing something subtle?

What about this:

	char *some_function()
	{
	  char *ptr;
	  ptr= "string";
	  another_function(ptr);
	}

Again, since another_function is not in the same block and "string" is
"local to a block" this would seem illegal.  But then so would:

	char *some_function()
	{
	  another_function("string");
	}

right?  And we know that's okay, cause printf does it.  What's the
story?



P.S. If this is dumb, please just ignore me, rather than flaming.  

Thanks in advance.
-- 
+------
|       Duke Robillard           
|       AT&T Bell Labs           {backbone!}att!m10ux!rgr
|       Murray Hill, NJ          rgr@m10ux.ATT.COM

chris@mimsy.UUCP (Chris Torek) (08/02/88)

In article <644@m10ux.UUCP>, rgr@m10ux.UUCP (Duke Robillard) writes:
>...  According to the first edition of K&R, stuff of the form "this is
>a string" is static (page 181).  This means they are "local to a block"
>(definition of static--page 182).

While static variables are local to the block in which they are defined,
that does not mean that they do not exist outside of that block.  Rather,
it means that they cannot be named outside of that block.

Automatic variables are also local to the block in which they are defined.
The primary difference between static and automatic variables is that
automatic variables are `live' (exist) only during the execution of that
block and any code called from that block, while static variables
exist after that block.

>	char *some_function()
>	{
>	  char *ptr;
>	  ptr= "string";
>	  return(ptr);
>	}

>It seems to me that "string" would only be defined inside some_function.

If strings did not have static storage duration, you would be
correct; and indeed, the alternative version

	char *some_function() {
		char buf[7];
		(void) strcpy(buf, "string");
		return (buf);
	}

is in fact invalid.

>What about ...
>	  ptr= "string";
>	  another_function(ptr);
>
>Again, since another_function is not in the same block and "string" is
>"local to a block" this would seem illegal.

Both `ptr' and `"string"' are still local to the function some_function(),
but here another_function() is called from within some_function(), hence
even without static storage duration, this would be legal.  Note that
the function another_function does not have access to the variable `ptr'
(no matter what [legal things] it does with its argument, `ptr' remains
unchanged).  It has indirect access to "string" only because it has its
own local variable (its argument) which has been made the same value
as `ptr'.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

chad@lakesys.UUCP (Chad Gibbons) (08/02/88)

In article <644@m10ux.UUCP> rgr@m10ux.UUCP (Duke Robillard) writes:
>I've got a question about string constants.  According to the first
>edition of K&R, stuff of the form "this is a string" is static (page 181).
>This means they are "local to a block" (definition of static--page 182).
>Okay, so does this mean that you can't do this:
>
>	char *some_function()
>	{
>	  char *ptr;
>	  ptr= "string";
>	  return(ptr);
>	}
>
>It seems to me that "string" would only be defined inside some_function.
>Is that right, or am I missing something subtle?

	When a string is declared inside a function or block, it is indeed
local to that function, and that function only. However, just like any other
variable, strings can be passed to functions, returned from functions,
compared, or what have you.
 
	[..so what about something like:]
>	char *some_function()
>	{
>	  another_function("string");
>	}
>
>[so this would be illegal,] right?  And we know that's okay, cause printf 
>does it.  What's the story?

	As I stated above, you an pass a string as your return value. There is
really no cause for alarm if I interperted your message correctly. Strings are
just another pointer, like any other variable. Quoting from "The C Programming
Language, Second Edition", Kernighan & Ritchie: "...because [static variables
declared in a function are local to that function,] no other function may have
direct access to them...each local variable in a function comes in existence
only when the function is called, and disappears when the function is exited."
Not that keypharse here is "direct access." As if true of all automatic
variables, no other program part can have "direct access" to that variable.
You an still freely pass that variable to and fro as you wish, however. 

	Consider the artifical sequence:

	char *testing(char *s, char *t);

	{...}

	char *testing(char *s, char *t)
	{
		if ((strcmp(s, t)) == 0) 
			return ("The strings are equal");
		else 
			switch (strcmp(s, t)) {
			case -1:
				return ("String s is < string t.");
				break;
			case  1: 
				return ("String s is > string t.");
				break;
			default:
				break;
			}
	}

	Here we have a function returning a string, with two string arguments.
String s and string t are passed from the calling function into testing which
uses the given pointer of the two strings. Both of these strings are then
passed to strcmp which lexigraphially compares the two strings and returns the
appropriate value. Depending on the returned value of strcmp, a string
constant is returned to the calling function.

	So you can see, strings, while being static - in most cases - within a
particular block, may be passed, compared, etc. in other functions, provided
the value is sent to that function/block.

	Hope this helped.

[Kernighan & Ritchie, The C Programming Language, Second Edition, Prentice
Hall publishing. Page 31, Section 1.10, Paragraph one.]


-- 
Chad Gibbons - UUCP:   {rutgers!uunet!uwvax}!lakesys!chad
Lake Systems - DOMAIN: chad@lakesys.UUCP
					-- "Red alert, Red alert"

pk-tle@nada.kth.se (Tommy Levitte) (08/03/88)

>I've got a question about string constants.  According to the first
>edition of K&R, stuff of the form "this is a string" is static (page 181).
>This means they are "local to a block" (definition of static--page 182).
>Okay, so does this mean that you can't do this:
>
>	char *some_function()
>	{
>	  char *ptr;
>	  ptr= "string";
>	  return(ptr);
>	}
>
>It seems to me that "string" would only be defined inside some_function.
>Is that right, or am I missing something subtle?

There are two kinds of statics:

 - External statics.
 - Internal statics.

External statics are defined outside functions, and internal are defined inside
functions.
External statics are reachable in the whole file, but internal statics are only
available in the function in which they are defined.

A string constant is an exception to this rule. It is available in the whole
file. This means that all your examples where legal.

-- 
-------------------------------------------------------------------------------
Tommy Levitte (pk-tle@draken.nada.kth.se or gizmo@kicki.stacken.kth.se)
-------------------------------------------------------------------------------

rgr@m10ux.UUCP (Duke Robillard) (08/04/88)

In article <12791@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes...
...an explaination of my string dilemma.  Thanks to Chris and everyone
else who helped me out.

During my search about this locality of statics business, I discovered
a pretty bizarre thing about strings.  I dunno if it's just my System
V compiler or what, but you can write to strings (since they're just
static arrays of characters?) Like:

main() 
{
	char *p;

	p= "abc";
	p[2]= 'd';
	printf("%s\n", p);   /* this will print "abd\n" */

        /* or, if you'd like to be even more obscure... */
	(p= "def")[2]= 'x';
	printf("%s\n", p);   /* this will print "abx\n" */
}

Pretty weird, huh?


-- 
+------
|       Duke Robillard 
|       AT&T Bell Labs           {backbone!}att!m10ux!rgr
|       Murray Hill, NJ          rgr@m10ux.ATT.COM

dean@homxb.UUCP (D.JONES) (08/04/88)

>         /* or, if you'd like to be even more obscure... */
> 	(p= "def")[2]= 'x';
> 	printf("%s\n", p);   /* this will print "abx\n" */
>
> +------
> |       Duke Robillard 
> |       AT&T Bell Labs           {backbone!}att!m10ux!rgr
> |       Murray Hill, NJ          rgr@m10ux.ATT.COM


	This must be how the "International Obfuscated C Code Contest" got
started. Want to see something even more obscure:

	2[p="def"] = 'x';
	printf("%s\n", p);

					Sorry about the waste of bandwidth,

						@:7)

/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/

signature()
{
	Dean_S_Jones("AT&T Bell Labs","HO 1K-426","{AT&T Gateways}!homxb!dean");

	if( MY_OPINIONS != (AT & T_OPINIONS))
		exit(0);
}

/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/

jwr@scotty.UUCP (Jim Reid) (08/04/88)

In article <652@m10ux.UUCP> rgr@m10ux.UUCP (Duke Robillard) writes:
<
<During my search about this locality of statics business, I discovered
<a pretty bizarre thing about strings.  I dunno if it's just my System
<V compiler or what, but you can write to strings (since they're just
<static arrays of characters?) Like:
<
<main() 
<{
<	char *p;
<
<	p= "abc";
<	p[2]= 'd';
<	printf("%s\n", p);   /* this will print "abd\n" */
<
<        /* or, if you'd like to be even more obscure... */
<	(p= "def")[2]= 'x';
<	printf("%s\n", p);   /* this will print "abx\n" */
<}
<
<Pretty weird, huh?

Could just be your compiler.
I tried it on my system(SUN 3/75 with SUN UNIX 4.2 release 3.5) &
got "dex" where you got "abx".

-- 

Jim Reid	{ames,cmcl2,rutgers}!rochester!kodak!fedsys!wally!jwr

--

rgr@m10ux.UUCP (Duke Robillard) (08/05/88)

In article <370@scotty.UUCP> jwr@scotty.UUCP (Jim Reid) writes:
)In article <652@m10ux.UUCP) rgr@m10ux.UUCP (Duke Robillard) writes:
)<main() 
)<{
)<	char *p;
)<      /* or, if you'd like to be even more obscure... */
)<	(p= "def")[2]= 'x';
)<	printf("%s\n", p);   /* this will print "abx\n" */
                                                 ^^^typo
)<}

)I tried it on my system(SUN 3/75 with SUN UNIX 4.2 release 3.5) &
)got "dex" where you got "abx".

    My typo--"dex" is the weird thing I got, too.

    Like they same in /usr/games/fortune, "Make sure the comments
match the code."
-- 
+------
|       Duke Robillard 
|       AT&T Bell Labs           {backbone!}att!m10ux!rgr
|       Murray Hill, NJ          rgr@m10ux.ATT.COM