Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!usc!brutus.cs.uiuc.edu!uakari.primate.wisc.edu!ames!haven!mimsy!chris From: chris@mimsy.umd.edu (Chris Torek) Newsgroups: comp.lang.c Subject: Re: Is this kosher? Message-ID: <21144@mimsy.umd.edu> Date: 6 Dec 89 22:57:59 GMT References: <21122@mimsy.umd.edu> <3248@hub.UUCP> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 99 >In article <21122@mimsy.umd.edu> I wrote: >> f() { char array[12]; ... } In article <3248@hub.UUCP> 6600pete@hub.UUCP writes: >What's the use of declaring such a thing beyond passing a pointer to it to >another module? (BTW, IMHO, this one use of the declaration runs counter to >intuitive programming practices because it peppers the .c file with things >that go in the binary executable image file instead of on the stack.) I do not understand this question. A local array is exactly as useful as N local variables that can be addressed randomly (since that is what it is). It also typically does go on a stack (C does not say what a `stack' might be; some implementations might, e.g., put small arrays into registers, if the machine architecture permits it). If you mean instead `what is the use of declaring a static array beyond' etc., you need some sort of stable object if it is intended to last beyond the activation of the function that contains it. Some people disapprove of this practise on principle, since it leads to strange results in cases like printf("time1: %stime2: %s", ctime(&t1), ctime(&t2)); since ctime() tends to use static storage. (Remember that ctime's return points to a NUL-terminated string whose last printing character is a newline, hence no \n in the printf above.) The alternatives, however, are sometimes just as bad: char *ct1, *ct2; ct1 = new_ctime(&t1); ct2 = new_ctime(&t2); printf("time1: %stime2: %s", ct1, ct2); free(ct1); free(ct2); or char ct1[CTIME_SIZE], ct2[CTIME_SIZE]; printf("time1: %stime2: %s", ctime(&t1, ct1), ctime(&c2, ct2)); The former requires heap allocation at runtime, while the latter requires deciding on a CTIME_SIZE in advance and sticking to it (even if it later proves to be too small). (Ctime is a bad example here since it already promises a fixed format.) >>Some entities---global variables and >>all functions---*always* have static duration. The confusion comes in >>here, as the `static' keyword can be applied to them, this time >>changing not their duration (which is already static) but rather their >>linkage. Static globals get internal linkage, which means that their >>names do not appear to exist outside the one file... >IMHO, this is a weakness in the standard. Has it been bashed out before? How can it be a weakness in the standard when it was required by K&R-1? It *could* be considered a weakness in C, that this keyword (`static') was overloaded to also mean `private' in various circumstances. However, it is worth pointing out that not all possible combinations can be had. In particular, if an object's duration is to be automatic, then object must declared in a block, and cannot have linkage. This leaves only static-duration objects to consider. These can have scope and linkage. List all combinations, and you will find that some are nonsensical: scope: (choices are block and file) linkage: (choices are none, internal, external) if scope = block: linkage = none is sensible linkage = internal is not (you have to name the object to use it, and block scope prevents naming it) linkage = external is not (same problem) if scope = file: linkage = none is not sensible linkage = internal is sensible (a private global name) linkage = external is sensible (a public global name) By assigning a `sensible' default action (with no modifier), one can see that only one modifier is needed for file scope names (to change private to public or vice versa), and no modifiers are needed for block scope names. Thus, one can reuse an existing keyword that is not applicable to file scope names to be the private/public modifier. The keyword need not be `static'---e.g., `auto' would have worked, or even `for' or `goto'. This is not to say that avoiding keywords for the sake of avoiding keywords is necessarily a good thing, or that I agree with the choice of `static' as a modifier to imply `private'. (Note that I have NOT told you what choices I would make! I say only that one can make the above argument. Whether I believe in it is not really a matter for comp.lang.c.) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@cs.umd.edu Path: uunet!mimsy!chris