greg@utcsri.UUCP (Gregory Smith) (12/07/86)
>In article <7374@utzoo.UUCP>, henry@utzoo.UUCP writes: >> Can you name a few? Extern is the way it has always been in C; compilers >> which default to static are broken. (Please don't cite C++, that isn't C.) >> -- In article <6430@alice.uUCp> bs@alice.UUCP writes: > >Most (all?) C compilers and lint will accept the following program: > >file1: > > typedef int I; > I i = 1; > >file2: > typedef char* I; > I p = "asdf"; > >Is it legal? Personally, I think not because the name I which is external by >default has two definitions (but the C++ compiler also accepts it). > But the storage class is given: 'typedef'. See pg 200, 8.8. In C, there are really only three 'Storage Classes' per se: static, auto, and register (the heap is supported entirely by run-time code). Auto is on the stack and static is at a constant address. All functions are static in this sense. However, storage class specifiers are used to specify more than just Storage Class. The concept of 'extern' has nothing to do with where an object is stored, but rather refers to the scope of its name during linking. 'typedef' names such as 'I' above are not objects and do not exist after compilation. So it makes no sense to apply a Storage Class of any form to 'I'. You are suggesting that the 'link-time scope' rules should be extended to typedefs (if only to make the example illegal), but neither of these concepts apply to 'Storage Class'. They are two different things which sc-specifiers have been made to do in addition to specifying Storage Class. It is worth noting at this point that the default storage class (!=Storage Class) for top-level data definitions is neither static nor exactly extern: static int a; int b; /* all three mean different things */ extern int c; --------------- cc -S --------- .lcomm _a,4 .comm _b,4 The definition of 'b' produces a common-block definition while 'c' does not. Under this implementation of C, you can write 'int b' in more than one file, but under many others, you can write 'int a' in only one file, and all others must say 'extern int b'. So there are three 'storage classes' (really link-time scope classes) for top-level objects: (1) static: object is defined here in this file and is not externally visible. (2) <none>: object is defined here in this file and *is* externally visible. (3) extern: object is not defined here but is available externally. ...with a few exceptions for convenience: char *getenv(); is treated as 'extern char *getenv()' since it is obviously not defined there. A definition of type (3) can exist in the same file with a (2) and then the type (3) definitions have no effect, other than allowing forward definition of type. Again, all top-level objects have static Storage Class. ..and of course... (4) typedef: not an object but a type, obviously not visible externally. -- ---------------------------------------------------------------------- Greg Smith University of Toronto UUCP: ..utzoo!utcsri!greg Have vAX, will hack...
karl@haddock.UUCP (12/13/86)
In article <3745@utcsri.UUCP> greg@utcsri.UUCP (Gregory Smith) writes: >So there are three 'storage classes' (really link-time scope classes) >for top-level objects: > >(1) static: object is defined here in this file and is not externally visible. >(2) <none>: object is defined here in this file and *is* externally visible. >(3) extern: object is not defined here but is available externally. Which brings up an interesting question: How do you declare an object which is not being defined at this point and is not available externally? Is there a portable way to make a forward declaration of a static variable? (I've been using "extern", but I wonder if that really works on all compilers.) Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
henry@utzoo.UUCP (Henry Spencer) (12/16/86)
> ... How do you declare an object which > is not being defined at this point and is not available externally? Is there > a portable way to make a forward declaration of a static variable? (I've been > using "extern", but I wonder if that really works on all compilers.) Alas, it's not X3J11-compliant. The current X3J11 drafts (well, the most current that I've seen -- I haven't got the official public-comment one yet) say that the first appearance of the name makes the rule, so you must say "static" on its first appearance. Unfortunately, a lot of existing compilers don't like this. (For that matter, *I* don't like it, but I am not optimistic about getting it changed.) My current custom is to declare variables like that with "STATIC int foo;" and then feed the compiler something suitable with a -DSTATIC=whatever. -- Henry Spencer @ U of Toronto Zoology {allegra,ihnp4,decvax,pyramid}!utzoo!henry