chris@mimsy.UUCP (Chris Torek) (08/05/88)
In article <503@draken.nada.kth.se> pk-tle@nada.kth.se (Tommy Levitte) writes: (text in []s his, but moved) >There are two kinds of statics: > - External statics [defined outside functions]. > - Internal statics [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. This is correct, but mixes up two separate concepts (well, perhaps this is reasonable, since the same keyword is used for both). >A string constant is an exception to this rule. This, however, is false. (You too have confused scoping and storage, at least in this explanation.) [text written _like_this_ represents emphasis] Static has two meanings. It is a _storage_class_specifier_, and it is a (link-time) _scope_specifier_. These should be considered separately. First, all local variables, no matter what their storage class, are locally (block) scoped. The differences between the declarations of x, y, and z below are in their storage classes, not their scopes. f() { int x; /* auto storage (the default) */ register int y; /* register storage */ static int z; /* static storage */ ... All of these variables are accessible in f, and in any sub-blocks within f() (unless they are hidden by a redeclaration). `x' and `y' come into existence when f() is called, and disappear when f() returns; new instances appear if f() is called recursively. `z', however, exists independent of f(): it has _static_storage_. There is only one copy of z; it is always there. It can only be _named_ from f(), but it is there whether it can be named or not. While all local variables are of storage class `auto' unless otherwise specified, global variables and functions are _always_ of storage class `static'. That frees the keyword for its second meaning: global variables and functions can be of _file_scope_ or _program_scope_. Normally, globals have program scope, but adorning a global definition with the keyword `static' makes it instead have file scope. Objects with file scope cannot be named outside of the source file that defines them; objects with global scope can be so named, by declaring them as external in another source file. Essentially, tagging a function or a global variable `static' makes it hidden, so that no one but you can find it. (It also allows you to make two or more different objects with the same name, whether or not you meant to do so, by using the same name in different files. Since each file refuses to disclose its statics, each file gets only its own version.) Finally, returning to string constants: these are unnamed objects, and hence the scoping rules for names are irrelevant. There simply is no name to be scoped. The objects do, however, have static storage duration: they exist at all times. Thus, once you have a pointer to a string constant, you can follow that pointer at any time. The string shall not vanish from underfoot, unless the whole program vanishes with it. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
jbeard@quintus.uucp (Jeff Beard) (08/06/88)
% Finally, returning to string constants: these are unnamed objects, and % hence the scoping rules for names are irrelevant. There simply is no % name to be scoped. The objects do, however, have static storage duration: % they exist at all times. Thus, once you have a pointer to a string % constant, you can follow that pointer at any time. The string shall % not vanish from underfoot, unless the whole program vanishes with it. 1) program scoped static char * foo may be altered anywhere by any procedure and thus the original string reference will be lost to all, even though the string it self persists. static char * header; header = " Center Heading For Report "; .... printf(header); /* performs as expected */ .... header = " Center Footing For Report "; .... printf(header); /* yields a FOOTING as a Header ... OhMy! */ 2) which brings up another storage class often forgotten altogeter: READONLY as in a format string given for printf() printf("text %c not of type %s\n" args, ..); xstr() collects said strings to reduce storage costs at possible expense of memory thrashing to get at a non-local page.
chris@mimsy.UUCP (Chris Torek) (08/08/88)
In article <12840@mimsy.UUCP> [and why does our netnews software use .UUCP?] I wrote: >>string constants ... do, however, have static storage duration .... In article <255@quintus.UUCP> jbeard@quintus.uucp (Jeff Beard) writes: >1) program scoped static char * foo may be altered anywhere by any procedure > and thus the original string reference will be lost to all, even though > the string it self persists. [example deleted] Certainly. >2) which brings up another storage class often forgotten altogeter: > READONLY as in a format string given for printf() In the dpANS, read-only (called `const') is considered a `qualifier' rather than a storage class. Strangely, while "string"s are allowed to be read-only, they have type `array of char' rather than `array of const char'. (I think this is a mistake.) > printf("text %c not of type %s\n" args, ..); > xstr() collects said strings to reduce storage costs at possible > expense of memory thrashing to get at a non-local page. The xstr program actually collects *all* quoted strings, and replaces each with something of the form `&xstr[<constant>]'. This is annoying; the common sequence #ifndef lint static char sccsid[] = "@(#)blort.c 4.2 (Berkeley) 8/8/88"; #endif fails to compile, since it becomes static char sccsid[] = &xstr[234]; One must write static char *sccsid = "@(#)blort.c 4.2 (Berkeley) 8/8/88"; which wastes a few bytes of storage per sccsid (since each id is different). -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris