[net.lang.c] typeof

ok@edai.UUCP (Richard O'Keefe) (07/24/84)

     I know the C standards group are trying to minimise changes
to the language, but there is one change which shouldn't do much
harm and would help people writing macros.  Let

	typeof <thing>

(where <thing> is whatever sizeof <thing> would allow) be used
as a type specifier.  Why would this be useful?  So that people
could define macros like

#define swap(x,y) {typeof x  *ZQ1 = &(x), *ZQ2 = &(y), t;\
		   t = *ZQ1, *ZQ1 = *ZQ2, *ZQ2 = t;}
/*  If there is a better way of defining this to work when
    x and y may contain arbitrary side-effective expressions
    I'd like to know it.
*/
#define SetNull(x) x = (typeof x)(0)

     The definition should explicitly say that the <thing> is
NOT evaluated (otherwise "swap" won't work).

     Someone said that the standard allows white space before a
sharp.  I hope this was a misunderstanding, and that explicitly
allowing white space after a sharp was meant.  Till now people
have been able to use " #" for tools that manipulate C code,
secure in the knowledge that C can't use sharps anywhere, and
the preprocessor can only see them in the first column.  (E.g.
there is a tool that lets you write end-of-line comments like
Ratfor instead of ugly /**/ filth.)  This change would break
those tools.  I can't see what the change is FOR; if you're
worried about the indentation you can leave the sharp at the
left margin and indent the keyword.

     Re the use of
#define	QUOTE(X) X
#define CONCAT(x,y) QUOTE(x)y
it was my understanding that the preprocessor was entitled to
include the newline (or a corresponding space) that ended the
definition of QUOTE in its expansion, so might not CONCAT(a,b)
expand to "a b"? The ONLY satisfactory answer to this problem is
for some public-spirited hero to write a public domain C
preprocessor in (sub-)standard C and send it to net.sources.
I'd do it myself, but I haven't got the time right now.

     This business of 6 letter external names, I don't
understand it.  COBOL has had 30-character names for YEARS, and
several COBOL compilers have a form of separate compilation.  If
a linker or object module format can handle 30-character
monocase names with hyphens, it can handle 30-character monocase
names with underscores (mapped to hyphens).  I suppose we should
be grateful that no-one is worried about IBM 1130 compatibility
or we'd have 5 letter external names!

jim@ism780b.UUCP (08/01/84)

#R:edai:-444000:ism780b:25500013:000:1647
ism780b!jim    Jul 23 11:12:00 1984

>      Someone said that the standard allows white space before a
> sharp.  I hope this was a misunderstanding, and that explicitly
> allowing white space after a sharp was meant.  Till now people
> have been able to use " #" for tools that manipulate C code,
> secure in the knowledge that C can't use sharps anywhere, and
> the preprocessor can only see them in the first column.  (E.g.
> there is a tool that lets you write end-of-line comments like
> Ratfor instead of ugly /**/ filth.)  This change would break
> those tools.  I can't see what the change is FOR; if you're
> worried about the indentation you can leave the sharp at the
> left margin and indent the keyword.

Unfortunately, the standards committee seems particularly unsavvy about the
preprocessor.  Most of the discussion I have seen in the minutes indicates
that they have never looked at the standard cpp implementation in an attempt
to resolve detailed undocumented semantic questions.  And in this case,
they seem to be completely unaware of or unwilling to consider the fact that
cpp has been used as an external processor independent of C, and that
it even has its own manual page in SysV.  This business about ignoring
whitespace *before* the sharp reminds me of "The Hunting of the Snark",
in which the Bellman, seeing "No one shall speak to the Helmsman" in the
nautical rules, added "and the Helmsman shall speak to no one" as an "obvious"
extension.  This information was provided in a footnote explaining the passage
"the rudder got mixed with the bowsprit sometimes" (the Helmsman was the only
one who knew better).

-- Jim Balter, INTERACTIVE Systems (ima!jim)

cottrell@nbs-vms.ARPA (02/07/85)

/*
> I would like to sample the community on a possibly useful construct
> 	typeof(foo)
> which is the type of expression foo.  It is similar in utility to sizeof().
> 
> When doing storage allocation with malloc the worst way to do it is:
> 	int *foo;
> 	foo = (int *)malloc(sizeof(int) * nelts);
> 
> A more sophisticated way of doing it is:
> 	int *foo;
> 	foo = (int *)malloc(sizeof(*foo) * nelts);
> 
> I like to use the above as I don't have to change the arguments to malloc
> if I change the type declaration of foo.  I do have to change the type
> cast to the new type however to keep lint happy.
> 
> It would be nice to be able to say:
> 	int *foo;
> 	foo = (typeof(foo))malloc(sizeof(*foo) * nelts);
> 
> In this case, if one changed the declaration of foo then one
> would not have to change the executable line.
> 
> Yes, I do realize that you can come darn close to this.  You can put the two
> lines you have to change together. Which is better than nothing.
-> 	int *foo;
-> 	typedef int *foo_t;
-> 	foo = (foo_t)malloc(sizeof(*foo) * nelts);
> 
> But the typeof() construct would not require the typedef declaration!
> 
> Is such a typeof() construct available in C?  Should it be?

I like it! However, you only have to change one of the `->' lines if
you do the following:

	typedef int *foo_t;
	foo_t foo;
	foo = (foo_t)malloc(sizeof(*foo) * nelts);

`Foo' is always of type `foo_t'. Be careful to keep from putting your
foo_t in your mout_h (like me) :-)
*/