jgm@spice.cs.cmu.edu (John Myers) (11/14/86)
Keywords: In article <4220@ut-ngp.UUCP> dlnash@ut-ngp.UUCP (Donald L. Nash) writes: >Why are typedef names in the same name space as variable names?... If they weren't, then what would the output of the following program be? #include <stdio.h> main() { typedef car foo; long foo; printf("%d\n",sizeof(foo)); }
ballou@brahms (Kenneth R. Ballou) (11/16/86)
In article <1092@spice.cs.cmu.edu> jgm@spice.cs.cmu.edu (John Myers) writes: >In article <4220@ut-ngp.UUCP> dlnash@ut-ngp.UUCP (Donald L. Nash) writes: >>Why are typedef names in the same name space as variable names?... > >If they weren't, then what would the output of the following program be? > >#include <stdio.h> >main() >{ > typedef car foo; Is this a typo, and supposed to be typedef char foo ? > long foo; > > printf("%d\n",sizeof(foo)); >} I don't see that there is a question here. Sizeof is *NOT* a function, as was quite thoroughly discussed some time back in this group. Note that (foo) in this case is the syntax of a type cast, and in this case, sizeof returns the size of a datum of type foo (in this case, 1). If, however, you were to write sizeof foo , you would then get the size of a long integer on your machine. References: K&R: page 126 (explains sizeof (object) and also points out that sizes are given in unspecified units called "bytes," which are the same size as a char); page 187 (gives two forms of the *operator* sizeof, namely sizeof expression and sizeof (type-name) ); page 188 (defines the meaning of the constructs involving sizeof and also notes that "byte" is the space required to hold a char *in all existing implementations*). -------- Kenneth R. Ballou ...!ucbvax!brahms!ballou Department of Mathematics ballou@brahms.berkeley.edu University of California Berkeley, California 94720
greg@utcsri.UUCP (Gregory Smith) (11/16/86)
allou@brahms (Kenneth R. Ballou) writes: >jgm@spice.cs.cmu.edu (John Myers) writes: >>dlnash@ut-ngp.UUCP (Donald L. Nash) writes: >>>Why are typedef names in the same name space as variable names?... >> >>If they weren't, then what would the output of the following program be? >> >>#include <stdio.h> >>main() >>{ >> typedef char foo; >> long foo; >> >> printf("%d\n",sizeof(foo)); >>} > >I don't see that there is a question here. Sizeof is *NOT* a function, as was >quite thoroughly discussed some time back in this group. Note that (foo) in >this case is the syntax of a type cast, and in this case, sizeof returns and also the syntax of a long expression. >the size of a datum of type foo (in this case, 1). If, however, you were to >write sizeof foo , you would then get the size of a long integer on your >machine. References: K&R: page 126 (explains sizeof (object) and also >points out that sizes are given in unspecified units called "bytes," which >are the same size as a char); page 187 (gives two forms of the *operator* >sizeof, namely sizeof expression and sizeof (type-name) ); page 188 (defines >the meaning of the constructs involving sizeof and also notes that "byte" >is the space required to hold a char *in all existing implementations*). > Objection sustained. If this were the only problem with putting typedefs and variable names in separate spaces, then it would be probably be resolved as you said in the given case. However, it ain't. Having written a C parser, I can testify that it is imperative that the two be in the same space. It must be possible to distinguish the end of declarations at the start of a block. The last declaration ( if any ) is not delimited in any way - the parser must be able to determine that the next 'thing' is a statement and not a declaration. Since declarations are structured completely differently from statements, it really helps if the distinction can be made very early ( i.e. after looking at one token ). typedef char foo1; int foo2(); char *abc; d(){ foo1 (*xyz); /* declare xyz as pointer to char */ foo2 (*abc); /* call foo2 with *abc as parameter */ ... } So if you allow typedefs and variables to be in separate spaces, and change foo1 and foo2 to foo, how do tell whether foo(*abc) is a declaration or a statement? Less extreme examples can be constructed: int foo3; ... foo1 * xyz; This is also legal, but doesn't do anything. Now, change foo1,foo3 to 'foo'. You can't expect the *parser* to look at the construction "foo * xyz;" and think 'well that would be silly if foo was an int, so it must be a typedef'. "It is agreed that the ice is thin here." - K&R, pg 206 -- ---------------------------------------------------------------------- Greg Smith University of Toronto UUCP: ..utzoo!utcsri!greg Have vAX, will hack...
wohler@sri-spam.istc.sri.com (Bill Wohler) (11/18/86)
In article <2183@sdcsvax.UCSD.EDU> bruss@sdcsvax.UUCP (Brian Russ) writes: > If [typedefs and variables] weren't in the same name space, > you could, in addition to the above, write: > > struct foo { /* ... */ }; > > foo foo; > > Yuch! Do you really want/need this flexibility? In my opinion, >it's better the way it is now. i haven't thought of an example which would necessitate having typedefs and variables in the same name space. it is very common to have: struct foo {...}; ... struct foo foo; thinking of different names for the structure and the variable becomes difficult when we just hack and don't expand our vocabulary reading faulkner or didion. ;-) --bw
tim@ism780c.UUCP (Tim Smith) (11/21/86)
There is already a problem with telling when the declarations end. Consider this program: main() { a; /* declare an integer variable */ a = 1; /* put something in it */ } Every C compiler I have tried complains about an undeclared variable on line 2. If "a" is a global, they have no problem: a; main() { a = 1; } -- emordnilapanalpanama Tim Smith USENET: sdcrdcf!ism780c!tim Compuserve: 72257,3706 Delphi or GEnie: mnementh
jsdy@hadron.UUCP (Joseph S. D. Yao) (11/24/86)
In article <307@cartan.Berkeley.EDU> ballou@brahms (Kenneth R. Ballou) writes: >In article <1092@spice.cs.cmu.edu> jgm@spice.cs.cmu.edu (John Myers) writes: >>In article <4220@ut-ngp.UUCP> dlnash@ut-ngp.UUCP (Donald L. Nash) writes: >>>Why are typedef names in the same name space as variable names?... >>#include <stdio.h> >>main() >>{ >> typedef car foo; >> long foo; >> printf("%d\n",sizeof(foo)); >>} >I don't see that there is a question here. Sizeof is *NOT* a function, as was >quite thoroughly discussed some time back in this group. Note that (foo) in >this case is the syntax of a type cast, and in this case, sizeof returns >the size of a datum of type foo (in this case, 1). (foo) is also an expression. If the typedef were not present, this would still be a legal C program, with an unambiguous compilation: the size of the long int "foo" would be printed out. As it is, I believe either interpretation is "correct". Thus, purely BTW, this can be considered a bad program -- I think it's not a good idea to use a name for more than one purpose, when a less ambiguous way of doing the same thing can be found. As I mentioned before, to keep people honest and as MY OWN PERSONAL preference of style, I use the parentheses in both cases. (Emphasis mine, not zippy's or root boy's -- don't flame if it's just not your own personal style.) -- Joe Yao hadron!jsdy@seismo.{CSS.GOV,ARPA,UUCP} jsdy@hadron.COM (not yet domainised)
greg@utcsri.UUCP (Gregory Smith) (11/26/86)
In article <4647@ism780c.UUCP> tim@ism780c.UUCP (Tim Smith) writes: >There is already a problem with telling when the declarations end. >Consider this program: > > main() { > a; /* declare an integer variable */ > a = 1; /* put something in it */ > } > >Every C compiler I have tried complains about an undeclared variable on >line 2. If "a" is a global, they have no problem: > > a; > main() { > a = 1; > } In the first example, line 2, 'a;' is a statement, to wit, the expression 'a'. It is an error only because there is no 'a' in scope. Declarations inside blocks must specify a type or a storage class. I am not saying that this is perfectly consistent; however it is thoroughly documented. In fact any C compiler that doesn't complain about the first example must be broken in a nasty way. Given this rule, there is no ambiguity in determining whether a thing in a block is another declaration or the first statement. If it starts with a type/storage-class specifier keyword, it is a declaration. If it starts with a currently defined typedef identifier, it is also a declaration. Anything else is either a statement or a syntax error. Do you expect to be able to declare the external function foobar as below? func(){ foobar(); /* declare ext. function foobar */ foobar(); /* call it */ } -- ---------------------------------------------------------------------- Greg Smith University of Toronto UUCP: ..utzoo!utcsri!greg Have vAX, will hack...
tim@ism780c.UUCP (Tim Smith) (12/02/86)
In article <3692@utcsri.UUCP> greg@utcsri.UUCP (Gregory Smith) writes: >>There is already a problem with telling when the declarations end. >>Consider this program: >> >> main() { >> a; /* declare an integer variable */ >> a = 1; /* put something in it */ >> } >> >In the first example, line 2, 'a;' is a statement, to wit, the >expression 'a'. It is an error only because there is no 'a' in scope. >Declarations inside blocks must specify a type or a storage class. I >am not saying that this is perfectly consistent; however it is >thoroughly documented. Where is this documented? K&R say that the type may be left out of declarations ( giving "int" as the default ). And they mention a problem explicitly with typedefs. I don't see anywhere that says I must specify a type in other cases ( on the other hand, I haven't looked very hard. I may have missed it. ). -- emordnilapregnolanalpanama Tim Smith USENET: sdcrdcf!ism780c!tim Compuserve: 72257,3706 Delphi or GEnie: mnementh
pdg@ihdev.UUCP (P. D. Guthrie) (12/03/86)
In article <4743@ism780c.UUCP> tim@ism780c.UUCP (Tim Smith) writes: >Where is this documented? K&R say that the type may be left out of >declarations ( giving "int" as the default ). And they mention a >problem explicitly with typedefs. I don't see anywhere that says I >must specify a type in other cases ( on the other hand, I haven't looked >very hard. I may have missed it. ). Well, I don't see them coming right out and saying it, but it is strongly implied in the text and enforced in the grammar. The exceptions are when you have a storage class identifier (eg register) or when it is an arg to a function (it defaults to int). Something interesting that is in the text though is the way that the default sc-specifiers are assigned. K&R state that the default is auto inside a function and *extern* outside. It seems to be *static* in most C implementations these days. -- Paul Guthrie We come in peace, ihnp4!ihdev!pdg We bring BEER!
greg@utcsri.UUCP (Gregory Smith) (12/04/86)
In article <4743@ism780c.UUCP> tim@ism780c.UUCP (Tim Smith) writes: >>Declarations inside blocks must specify a type or a storage class. I >>am not saying that this is perfectly consistent; however it is >>thoroughly documented. > >Where is this documented? K&R say that the type may be left out of >declarations ( giving "int" as the default ). And they mention a >problem explicitly with typedefs. I don't see anywhere that says I >must specify a type in other cases ( on the other hand, I haven't looked >very hard. I may have missed it. ). Well, I take this back. Can't find it in K&R anywhere. It should be mentioned on page 201 in 9.2, especially. It *has* to be a rule, since there are umpteem valid declarations that become valid statements when you don't give a storage class or type: int i=1; extern foo(); etc. -- ---------------------------------------------------------------------- Greg Smith University of Toronto UUCP: ..utzoo!utcsri!greg Have vAX, will hack...
henry@utzoo.UUCP (Henry Spencer) (12/04/86)
> ...default sc-specifiers are assigned. K&R state that the default is auto > inside a function and *extern* outside. It seems to be *static* in most > C implementations these days. 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.) -- Henry Spencer @ U of Toronto Zoology {allegra,ihnp4,decvax,pyramid}!utzoo!henry
bs@alice.UUCP (12/05/86)
In article <7374@utzoo.UUCP>, henry@utzoo.UUCP writes: > > ...default sc-specifiers are assigned. K&R state that the default is auto > > inside a function and *extern* outside. It seems to be *static* in most > > C implementations these days. > > 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.) > -- > Henry Spencer @ U of Toronto Zoology > {allegra,ihnp4,decvax,pyramid}!utzoo!henry 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). The default storage class specifiers are identical in C and C++ so the glib remark about C++ is irellevant in the context. What is different about C++ in this context is that structure tags are in the same name space as identifiers (including typedef names). For example, the following is not C++: struct s { int a; }; struct s s; As it happens, the generally available C++ implementation accepts this as an aid to people mixing C and C++. On a more general note what does it take for a C-like language/implementation to be ``not C''? For example, is the C-like language used on many UNIX systems ``not C'' for failing accept this (perfectly legal) C program?: typedef double T; f() { typedef int T; } (C++ accepts it, but on many systems its ``code generator'', cc, chokes on its perfectly legal intermediate C). C++ is C by the simple test of its compiler accepting a larger subset of what is accepted to be C than most C compilers. Is a ``C-like language'' with a keyword like ``near'' ``not C''? The compiler for such a C-like language does not accept the perfectly legal C program: main() { int near = 2; printf("%n\n",near); } Is a ``C-like language'' without the keyword ``enum'' C? Clearly, any C with an extension that renders even a single legal C program uncompilable is in a real sense ``not C''. One purpose of the ANSI C effort is to define a minimum standard for what should be called C, but is the minimum all that matters? If so, ought the ANSI C commitee abandon the different standards found in the proposal (I think their names are: ``conforming'', ``strictly conforming'', `hosted'', and ``embedded'' implementations - each in a real sense defines a different language)? I don't think so (this would imply 7 character names and several other horrors - including having to change just about every large C program written to date because of use of features not in ``strictly conforming ANSI C''). I don't think that any member of the ANSI C comitte wants to have ONLY a minimal standard and thereby stop further evolution of C. Hence the practical, but rather ad hoc, acceptance of unspecified extensions in (mearly) conforming implementations of C. C++ is not strictly conforming ANSI C (as proposed), but it is C. The problem is that it is also much more. In particular, being able to write things like class complex { double re, im; public: complex(double r, double i) { re=r; im=i; } friend complex operator+(complex a, complex b) { return complex(a.re+b.re, a.im+b.im); } }; f() { complex a = complex(1,2); complex b = a+complex(3,4); } precludes writing things like main() { int class = 2; printf("%n\n",class); } and struct complex { double re, im; }; struct complex complex; complex.re = 2;
gwyn@brl-smoke.ARPA (Doug Gwyn ) (12/06/86)
In article <6430@alice.uUCp> bs@alice.UUCP writes: >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). I see no more reason to consider the abbreviation `I' external than to do so for `COUNTER' in the following scenario: file1: #define COUNTER int COUNTER i = 1; file2: #define COUNTER long COUNTER l = 0; It appears to depend on whether one considers typedef to be a convenient shorthand or something more fundamental. If you adopt your view, then one needs to allow declarations such as: static typedef int I;
henry@utzoo.UUCP (Henry Spencer) (12/10/86)
> > 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.) > > The default storage class specifiers are identical in C and C++ so the glib > remark about C++ is irellevant in the context... Some private correspondence with Bjarne has cleared up a misunderstanding on my part. I was misled by (a) some confusing differences in terminology between C and the C++ book, and (b) the fact that early, pre-book, versions of C++ did indeed default to "static" (in the C meaning). Bjarne comments: "This was probably the right decision in the abstract, but in actual use it created so much resistance and confusion that I backed off." -- Henry Spencer @ U of Toronto Zoology {allegra,ihnp4,decvax,pyramid}!utzoo!henry
jsdy@hadron.UUCP (Joseph S. D. Yao) (12/15/86)
In article <4647@ism780c.UUCP> tim@ism780c.UUCP (Tim Smith) writes: > main() { a; a = 1; } >Every C compiler I have tried complains about an undeclared variable on >line 2. If "a" is a global, they have no problem: > a; main() { a = 1; } This is an illegal declaration, anyway. Declarations must contain at least one "storage class" specifier or one "type" specifier. A compiler that accepts the above is exhibiting a bug, not a feature. *** Stamp out programs that put arbitrary decrees on text shape *** -- Joe Yao hadron!jsdy@seismo.{CSS.GOV,ARPA,UUCP} jsdy@hadron.COM (not yet domainised)