Is this kosher?

Arthur B. Smith art at dinorah.wustl.edu
Wed Dec 6 09:34:20 AEST 1989


Forgive me if this has already been discussed....  I don't remember
seeing it recently, anyway.  Here is a much shortened version of what
I am doing, and I want to know if it's ok.  The particularly
questionable thing is marked.

typedef struct node
  {
  char        * str;
  struct node * next;
  } node;

void f ( )

  {
  node * listhd;

  if ( (listhd = (node *)malloc(sizeof(node))) == NULL )
    {
    cough_up_and_die();	/* Details not important */
    }
  else
    {
    listhd->str = "string literal";   /* This is the questionable line... */
    listhd->next = 0;
    recursive_function(listhd);	      /* ...given this usage */
    }
  return;
  }

    In particular, is it safe to assign the address of the string
literal in the list and assume that the contents of that address do
not change when in another function?

    As I RTFM, string literals have a static storage class, which
means that they are guaranteed to have the same contents inside the
block, but I am not clear on their linkage (which I think determines
whether they have the same contents outside the block as well).  K&R2
(since I don't have an ANSI draft) says:

"A string [literal] has type "array of characters" and storage class
static and is initialized with the given characters." 

and

"Static objects may be local to a block or external to all blocks, but
in either case retain their values accross exit from and reentry to
functions and blocks."  This is followed by how to delcare the linkage
for objects declared outside blocks using static and extern keywords, etc.

    I cannot find anywhere that indicates the linkage for the string
constant.  If my recursive_function() in the example above uses the
value in listhd->str (say for a strcmp()), can it be sure that the
string contains "string literal"?  If not, how do I assure that?
Do I have to do something like:

typedef struct node
  {
  char        * str;
  struct node * next;
  } node;

char * stick_around = "string literal";	    /* Yucko! */

int f ( )

  {
  node * listhd;

  if ( (listhd = (node *)malloc(sizeof(node))) == NULL )
    {
    cough_up_and_die();	/* Details not important */
    }
  else
    {
    listhd->str = stick_around;	/* What's in stick_around? */
    listhd->next = 0;
    recursive_function(listhd);
    }
  return;
  }

    This is certainly less readable.  I _am_ interested in portability
considerations, both theoretical and real (you can have your way with
the "weird" machines, Chris 8^).  I will try to follow this group, but
personal replies are also welcome.  Thanks in advance!

    art smith  (art at dinorah.wustl.edu  or ...!uunet!wucs1!dinorah!art)

Usual disclaimers apply.



More information about the Comp.lang.c mailing list