Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!wuarchive!dinorah!art From: art@dinorah.wustl.edu (Arthur B. Smith) Newsgroups: comp.lang.c Subject: Is this kosher? Keywords: Does a static exist outside its block? Message-ID: <1047@dinorah.wustl.edu> Date: 5 Dec 89 22:34:20 GMT Organization: Washington University (St. Louis) Lines: 90 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@dinorah.wustl.edu or ...!uunet!wucs1!dinorah!art) Usual disclaimers apply.