[net.lang.c] A useful construct for C ?

brooks@lll-crg.ARPA (Eugene D. Brooks III) (02/05/85)

References:

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?

ron@brl-tgr.ARPA (Ron Natalie <ron>) (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().
> 
>	....
>
> It would be nice to be able to say:
> 	int *foo;
> 	foo = (typeof(foo))malloc(sizeof(*foo) * nelts);
> 

Well first, would the C standard group's (void *)'s help here?

Actually, MALLOC really should know what alignment requirement is
required.  Right now it just takes the least common multiple of
all data types.  Should a similar builtin function (I'll use a
silly name here to avoid confusion:

	foo = (typeof foo) malloc(sizeof(*foo)*nelts, rons_typeof foo);

Where rons_typeof would yield something like an enum that could be checked
for in the Malloc routine.

-Ron

Doug Gwyn (VLD/VMB) <gwyn@Brl-Vld.ARPA> (02/07/85)

Since as you point out the required function can already be obtained
by typedef, why complicate matters by adding another similar feature?

guy@rlgvax.UUCP (Guy Harris) (02/09/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().
> >	....
> > It would be nice to be able to say:
> > 	int *foo;
> > 	foo = (typeof(foo))malloc(sizeof(*foo) * nelts);
> 
> Well first, would the C standard group's (void *)'s help here?

It would.  The cast to "typeof(foo)" isn't necessary for C (the compiler
knows enough to generate a coercion from the "char *" which, of course,
everybody declares "malloc" as (right?) to the "int *" that "foo" is).
It has no effect on "lint" here (S3 "lint") - in both cases, it bitches about
"illegal pointer combination" and "possible pointer alignment problem".
That's what the "void *" would eliminated - a "void *" is assumed to be
castable to any other pointer type, safely.  It's the responsibility
of the routine returning a "void *", or the programmer, to ensure that
the pointer is actually usable (e.g., that it's aligned on the most
restrictive boundary that the machine requires).

> Actually, MALLOC really should know what alignment requirement is
> required.  Right now it just takes the least common multiple of
> all data types.  Should a similar builtin function (be available)?

"lint" has a comment in it to the effect of "I wish we had 'alignof'".
That's exactly what you asked for; maybe it should be proposed to the
ANSI C Standards Committee?

	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy

kpmartin@watmath.UUCP (Kevin Martin) (02/10/85)

>> It would be nice to be able to say:
>> 	int *foo;
>> 	foo = (typeof(foo))malloc(sizeof(*foo) * nelts);
>
>Actually, MALLOC really should know what alignment requirement is
>required.  Right now it just takes the least common multiple of
>all data types.  Should a similar builtin function (I'll use a
>silly name here to avoid confusion:
>
>	foo = (typeof foo) malloc(sizeof(*foo)*nelts, rons_typeof foo);
>
>Where rons_typeof would yield something like an enum that could be checked
>for in the Malloc routine.
>
>-Ron


This sounds like a job for an 'alignof' operator:
    foo = (typeof foo) malloc(sizeof(*foo)*nelts, alignof(*foo) );

In addition, several implementations require a method of finding the
alignment of a type in order to implement <varargs.h> (or <stdarg.h>,
depending who you ask).
               Kevin Martin, UofW Software Development Group