[net.lang.c] runtime 'sizeof

robert@gitpyr.UUCP (Robert Viduya) (01/18/85)

[]

The other day I was modifying some source code when I came across something
that showed me one of the limitations of the sizeof operator.  Basically, I
had the following in a source file:

	extern struct s	a[];
		.
		.
		.
	    b = sizeof(a);
		.
		.
	
Needless to say, the compiler assigned 0 to b instead of the actual size of
the array.

Obviously, in order to handle things like this, C needs a runtime version
of sizeof.  I can see two ways of doing this.  One way is to have the size
of each variable stored as part of that variable (waste a bit of storage).
Another way is to implement it as a real function that 'knows' where all
the variables are and can compute the size of each (also can waste storage).

A third way, which I see to be the best, is to defer the evaluation of any
sizeof operation that references an external value to link/load time and put
a placeholder in its place.  The linker/loader would have to replace the
placeholder with the actual size of the external variable (since it knows
the size anyway).  This doesn't waste any unnecessary storage for 'hidden'
variables and also allows using the sizeof operator with external variables.

Comments anybody?

			robert
-- 
Robert Viduya
    Office of Computing Services
    Georgia Institute of Technology, Atlanta GA 30332
    Phone:  (404) 894-4669

...!{akgua,allegra,amd,hplabs,ihnp4,masscomp,ut-ngp}!gatech!gitpyr!robert
...!{rlgvax,sb1,uf-cgrl,unmvax,ut-sally}!gatech!gitpyr!robert

robert@gitpyr.UUCP (Robert Viduya) (01/20/85)

[]

Judging from mail I've recieved about the subject, I think I was a bit
unclear about the problem.  This should clear things up.

The problem is that the sizeof operator produces different answers
when used in two different source files.  I can declare the following
in one source file:

	  ...

	struct s a[] = { 
		{ "....",0,0,0 },
		{ ",,,,",1,1,1 },
	};

	  ...

	b = sizeof (a);

and have b be set to some number representing the size of a in bytes, but
I cannot refer to the same structure from another source file:

	  ...

	extern struct a[];

	  ...

	b = sizeof (a);		/* set to zero or a compiler error msg */

The array is defined and initialized to contain data.  Therefore, the
sizeof operator should work *regardless* of what source file it is used in.

			robert
-- 
Robert Viduya
    Office of Computing Services
    Georgia Institute of Technology, Atlanta GA 30332
    Phone:  (404) 894-4669

...!{akgua,allegra,amd,hplabs,ihnp4,masscomp,ut-ngp}!gatech!gitpyr!robert
...!{rlgvax,sb1,uf-cgrl,unmvax,ut-sally}!gatech!gitpyr!robert

guy@rlgvax.UUCP (Guy Harris) (01/21/85)

> A third way, which I see to be the best, is to defer the evaluation of any
> sizeof operation that references an external value to link/load time and put
> a placeholder in its place.  The linker/loader would have to replace the
> placeholder with the actual size of the external variable (since it knows
> the size anyway).  This doesn't waste any unnecessary storage for 'hidden'
> variables and also allows using the sizeof operator with external variables.

Nice, except that there's a lot more to this than just giving the linker
the ability to do a "sizeof".

Take, for example,

	a = sizeof(b)*2 + 3;

If "b" were an "extern" array with an empty dimension specifier, so that
this constant would have to be evaluated at link time, the linker would
have to be able to perform arbitrary computations.  There are several
linkers which can do this (the DEC PDP-11 and VAX linkers among them),
but to make the UNIX linker handle this you'd not only have to add a
"sizeof" operator to the linker but add the ability to do this sort of
"complex relocation" as well.

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

greenber@acf4.UUCP (ross m. greenberg) (01/28/85)

<>
What I always have is a little .h file:
= = = = = = = = = = =
#ifndef	NULL
#define	NULL	(int) 0
#endif

#ifndef NULLP
#define	NULLP	(char *)NULL
#endif
 = = = = = = = = = = =
Aside from being "portable", it really makes code easier to read because
you know which are apples and which are pears.

I also go the whole way with additional NULLs defined (NULLL, NULLS,
NULLD, NULLF, etc.), because this won't always work:

long	var;
	if (var == NULL)  {stuff}

Then of course the question is, will this work:

long	var;
	if (var) {stuff}

I've found that it doesn't always (flaky compilers!), so I have
made my code (when needed):

long	var;
	if (var != NULLL) {stuff}

Sloppy, but portable!!! (and easy to understand, even for me!)

Didn't we have this discussion about three months ago??


------------------------------------------------------
Ross M. Greenberg  @ NYU   ----> { allegra,ihnp4 }!cmcl2!acf4!greenber  <----

bsa@ncoast.UUCP (Brandon Allbery) (02/06/85)

As to the null pointer controversy, I've taken to using a derivative
of the technique Larry Wall uses in rn for all but the quick, sloppy
ultra-local (TRS-Xenix) programs:

#define Null(type) ((type *) 0)

...
	if ((fp = fopen(filename, "r")) == Null(FILE))
	    ...

You get the idea.  Easy to use and it makes the point (pun not intended)
evident.

--bsa
-- 
   Brandon Allbery @ decvax!cwruecmp!ncoast!bsa (..ncoast!tdi1!bsa business)
6504 Chestnut Road, Independence, Ohio 44131 +1 216 524 1416 (or what have you)

guy@rlgvax.UUCP (Guy Harris) (02/11/85)

> #define Null(type) ((type *) 0)
> 
> ...
> 	if ((fp = fopen(filename, "r")) == Null(FILE))
> 	    ...
> 
> You get the idea.  Easy to use and it makes the point (pun not intended)
> evident.

Although it isn't necessary; the compiler knows that the LHS of the "==" is a
"FILE *" so it can coerce the "0" to a null FILE *.  In ANSI Standard C
it can even be told that the Nth argument to a function is a FILE * and
will coerce 0 there; the only place this doesn't work is in functions
which take a variable number of arguments.  The main "offender" here is
"execl", which is just a bit of syntactic sugar - anything you can do with
"execl" you can do with "execv" at the expense of having to build an
argument vector somewhere else.

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