[comp.lang.c] Representation of NULL and 0.0

martin@mwtech.UUCP (Martin Weitzel) (12/15/89)

In article <1989Dec14.182113.5398@twwells.com> bill@twwells.com (T. William Wells) writes:
[most stuff deleted, because not significant for my question]
>
>Warning: null pointers and floating point zeros are *not*
>necessarily represented by bit patterns of all zero bits.

Sorry, my copy of the draft is not the most recent (we Europeans
seem to have no easy way, to get an up-to-date *A*NSI-Standard :-/),
but I allready guessed that a portable programm would require:

	foo(size_t n)
	{
		double *a;	/* no a[n] in C */
		a = malloc(n * sizeof *a);
		if (!a) abort();/* at least */
		{ size_t i = n; while (i--) a[i] = 0; }
		/* now we have an array of n zero-initialized double-s */
		/* and can do whatever we must do with it .... */
		:
		:
		free(a);
	}

If the type of "a" would have been int or long, one could ommit
the initialization loop and replace malloc with calloc, which may
have a faster way to zero the allocated space. (Am I right so far?)
Wouldn't it have been wise to add another 'calloc' for floating
types and NULL pointers, as the initializing feature of calloc
is weak in this respect? (As an aside, the pure existance of
such a function would have warned all programmers, who are still
in believe, they allways receive NULL-pointers or 0.0 from calloc).

Now, how is the situation with statically allocated data (esp.
not fully initialized arrays). The compiler 'knows' the exact
data type in this situation (other than calloc in the above example)
and could use 'the right' representation. What are the guarantees
of the standard: zero bits or NULL resp. 0.0?

-- 
<<< MW -- email: see header -- voice: 49-(0)6151-6 56 83 >>>

henry@utzoo.uucp (Henry Spencer) (12/17/89)

In article <545@mwtech.UUCP> martin@mwtech.UUCP (Martin Weitzel) writes:
>If the type of "a" would have been int or long, one could ommit
>the initialization loop and replace malloc with calloc, which may
>have a faster way to zero the allocated space. (Am I right so far?)

That's correct; integer data types are pretty much constrained to have
the obvious binary representation.  However, a malloc() followed by a
memset() is unlikely to be any slower than calloc().

>Wouldn't it have been wise to add another 'calloc' for floating
>types and NULL pointers, as the initializing feature of calloc
>is weak in this respect?...

What would you do about structs?  The very existence of calloc is
basically a botch.  It only works for a few data types, and there
is no way to build a more general version.

>Now, how is the situation with statically allocated data (esp.
>not fully initialized arrays). The compiler 'knows' the exact
>data type in this situation (other than calloc in the above example)
>and could use 'the right' representation. What are the guarantees
>of the standard: zero bits or NULL resp. 0.0?

Static initialization is guaranteed to happen as if by assignment of 0.
On a system where some datatypes do not use all-zero-bits for 0, the
compiler is going to have to work harder.
-- 
1755 EST, Dec 14, 1972:  human |     Henry Spencer at U of Toronto Zoology
exploration of space terminates| uunet!attcan!utzoo!henry henry@zoo.toronto.edu

bill@twwells.com (T. William Wells) (12/18/89)

In article <545@mwtech.UUCP> martin@mwtech.UUCP (Martin Weitzel) writes:
: >Warning: null pointers and floating point zeros are *not*
: >necessarily represented by bit patterns of all zero bits.
:
: Sorry, my copy of the draft is not the most recent (we Europeans
: seem to have no easy way, to get an up-to-date *A*NSI-Standard :-/),

Actually, most everyone gets it the same way: by calling someone
(is Global Engineering the only one?) and ordering a copy. It has
been just as difficult for us U.S.*A*mericans to get an up to date
standard.

: If the type of "a" would have been int or long, one could ommit
: the initialization loop and replace malloc with calloc, which may
: have a faster way to zero the allocated space. (Am I right so far?)

Yes. Also for short or char.

: Wouldn't it have been wise to add another 'calloc' for floating
: types and NULL pointers, as the initializing feature of calloc
: is weak in this respect? (As an aside, the pure existance of
: such a function would have warned all programmers, who are still
: in believe, they allways receive NULL-pointers or 0.0 from calloc).

Maybe. I'm of the opinion that calloc should simply go away. I
never use it.

: Now, how is the situation with statically allocated data (esp.
: not fully initialized arrays). The compiler 'knows' the exact
: data type in this situation (other than calloc in the above example)
: and could use 'the right' representation. What are the guarantees
: of the standard: zero bits or NULL resp. 0.0?

NULL or 0.0. The one case I didn't see covered was the initial
value of a union. It appears that the union is initialized as if
its first element were initialized, but I didn't see it say this
explicitly.

---
Bill                    { uunet | novavax | ankh | sunvice } !twwells!bill
bill@twwells.com

karl@haddock.ima.isc.com (Karl Heuer) (12/19/89)

In article <545@mwtech.UUCP> martin@mwtech.UUCP (Martin Weitzel) writes:
>Wouldn't it have been wise to add another 'calloc' for floating
>types and NULL pointers, as the initializing feature of calloc
>is weak in this respect?

You still wouldn't have a way to allocate a zeroed struct of mixed types.

Personally, I think a wiser move would be to get rid of calloc(), since its
initializing feature is largely useless and misleading (and since its other
"feature", namely multiplying the two arguments together, can be done just as
easily and probably more efficiently at the caller's end).  I suspect that the
Commitee generally agrees, but was forced to keep calloc() for historical
reasons.

>Now, how is the situation with statically allocated data...?

The pANS requires that a static-duration datum not covered by an explicit
initializer (or an automatic-duration datum which is part of an initialized
aggregate but beyond the end of the explicit initializer, K&R2 to the contrary
notwithstanding) must have an initial value of a properly-typed zero.  Thus,
a non-VAXlike implementation cannot simply put all uninitialized objects into
a "bss segment".  (But it could sort them by type and have an "all-bits-zero
segment", a "floating-point zero space", etc. if it's worth the effort.)

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint