[comp.lang.c] BSD bzero

jl57+@andrew.cmu.edu (Jay Laefer) (11/14/90)

[I'm asking the following in the context of ANSI C.]

I'm confused on an issue regargding NULL and the BSD function bzero().

I realize that the following assignments are equal:

char *fred;

fred = 0;
fred = (char *)NULL;

because the compiler is responsible for translating the zero bit pattern
into its internal representation of NULL.

But, given that bzero() directly fills an area with zeros, can I assume
that the following is equivalent to the above?

bzero(fred, sizeof (char *))

My gut reaction is no because this zeros out a block of memory and I'm
not guaranteed that the computer's internal representation of NULL is a
zero bit pattern.

Answers, anyone?

bruce@seismo.gps.caltech.edu (Bruce Worden) (11/15/90)

In article <AbEJW8e00VQfE4N0I3@andrew.cmu.edu> jl57+@andrew.cmu.edu (Jay Laefer) writes:

>char *fred;
>fred = 0;
> [ .... ]
>But, given that bzero() directly fills an area with zeros, can I assume
>that the following is equivalent to the above?

>bzero(fred, sizeof (char *))

>My gut reaction is no because this zeros out a block of memory and I'm
>not guaranteed that the computer's internal representation of NULL is a
>zero bit pattern.

It won't work, but not for the reason you stated.  bzero() will zero out 
sizeof(char *) bytes starting at the address `fred', which has not been 
initialized, so you will simply be zeroing out some memory at a random 
location.  I imagine that you meant to ask whether

	bzero((char *)&fred, sizeof(char *));

will work, in general.  And the answer is no, for the reason you stated.
(There may also be an issue as to whether (char *)&fred is an acceptable
argument to bzero().)  BTW, memset() would probably be better in an ANSI C 
program, since it is defined by the standard, and bzero() is not.
--------------------------------------------------------------------------
C. Bruce Worden                            bruce@seismo.gps.caltech.edu
252-21 Seismological Laboratory, Caltech, Pasadena, CA 91125

barmar@think.com (Barry Margolin) (11/15/90)

In article <AbEJW8e00VQfE4N0I3@andrew.cmu.edu> jl57+@andrew.cmu.edu (Jay Laefer) writes:
>[I'm asking the following in the context of ANSI C.]
>
>I'm confused on an issue regargding NULL and the BSD function bzero().
>
>I realize that the following assignments are equal:
>
>char *fred;
>
>fred = 0;
>fred = (char *)NULL;
>
>because the compiler is responsible for translating the zero bit pattern
>into its internal representation of NULL.

Actually, the compiler translates between the *integer constant 0* and its
internal representation of NULL.  It doesn't do anything with bit patterns.
For instance, the following is not equivalent to the above:

int zero = 0;
fred = zero;

Because zero is an integer variable, not an integer constant.

>But, given that bzero() directly fills an area with zeros, can I assume
>that the following is equivalent to the above?
>
>bzero(fred, sizeof (char *))

I assume you meant:

bzero (&fred, sizeof (char *));

>My gut reaction is no because this zeros out a block of memory and I'm
>not guaranteed that the computer's internal representation of NULL is a
>zero bit pattern.

Your gut reaction is correct.  Bzero() stores a zero bit pattern, which is
not required to be equivalent to a null pointer.  Bzero() is just a library
function, so it isn't required to know the type of object that its argument
is pointing to, and therefore can't be expected to store the type-dependent
0 there.

The same may be true for floating point types, e.g.

float fl;
bzero (&fl, sizeof (float));

might not put 0.0 into fl.  Bzero can only be expected to work as expected
when the first argument is a pointer to an integral type.

--
Barry Margolin, Thinking Machines Corp.

barmar@think.com
{uunet,harvard}!think!barmar

rjc@uk.ac.ed.cstr (Richard Caley) (11/15/90)

In article <1990Nov15.000129.27402@Think.COM> barmar@think.com (Barry Margolin) writes:

    Bzero can only be expected to work as expected
    when the first argument is a pointer to an integral type.

Just as a perverse question inspired by too much bad coffee, is this
the case?

Well, ok, one can _expect_ anything.

Does the standard demand that the bit pattern for then integer 0 be
`all zeros'. If someone was perverse enough to write a compiler which
made the mapping from bit patterns to integers/chars be something
other than one of the obvious ones (2s complement, 1s complement, etc)
would this be in violation.

Obviously all the standard operation would have to work (the bitwise
ones would be the killer). The only real way to tell the difference
would be to write some data raw to file and read it using some other
system. 

``Perverted Minds Want to Know''

--
rjc@uk.ac.ed.cstr		_O_
				 |<

chris@mimsy.umd.edu (Chris Torek) (11/15/90)

In article <AbEJW8e00VQfE4N0I3@andrew.cmu.edu> jl57+@andrew.cmu.edu
(Jay Laefer) asks:
>[does   char *fred; bzero((char *)&fred, sizeof fred)  put a nil pointer
  to char into `fred'?]
>My gut reaction is no because this zeros out a block of memory and I'm
>not guaranteed that the computer's internal representation of NULL is a
>zero bit pattern.

Your reaction is correct.  A fair amount of code (not just `BSD' code)
assumes that all nil pointers have zero bit patterns; this is one
reason the S1 project, which had tagged pointers and was going to use a
nonzero bit pattern for nil pointers, eventually gave up and
special-cased their C environment to allow all zero bits for nils:
it was more work to make things go fast than to make things go like
a {VAX, 68000, 80x86, ...}.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 405 2750)
Domain:	chris@cs.umd.edu	Path:	uunet!mimsy!chris

richard@aiai.ed.ac.uk (Richard Tobin) (11/15/90)

In article <RJC.90Nov15073451@brodie.uk.ac.ed.cstr> rjc@uk.ac.ed.cstr (Richard Caley) writes:
>Does the standard demand that the bit pattern for then integer 0 be
>`all zeros'.

3.1.2.5 (Types):

  The representation of integral types shall define values by use of a
  pure binary numeration system.

  [A footnote defines this as: A positional representation for
  integers that uses the binary digits 0 and 1, in which the values
  represented by successive bits are additive, beginning with 1, and
  are multiplied by successive integral powers of 2, except perhaps
  the bit with the highest position.]

In other words, yes.  Or at least that's what they mean.  I don't
actually see anything that stops a system that's 2s-complement with
the meaning of the sign bit reversed.  I suppose it depends on the
scope of the "except".

The intention is to allow 2s and 1s complement.

>Obviously all the standard operation would have to work (the bitwise
>ones would be the killer). 

Section 3.3 (Expressions) specifically notes:

  These [bitwise] operators return values that depend on the internal
  representations of integers, and thus have implementation-defined
  aspects for signed types.

>The only real way to tell the difference
>would be to write some data raw to file and read it using some other
>system. 

Since nothing is guaranteed about the external representation of data
written to binary streams, you can't even do this.  By the "as if"
rule, the hardware could use ternary Gray code, so long as the
compiler made the operators do the right thing.  And if it did,
there's nothing to stop it converting to and from 2s complement when
doing binary i/o.

-- Richard
-- 
Richard Tobin,                       JANET: R.Tobin@uk.ac.ed             
AI Applications Institute,           ARPA:  R.Tobin%uk.ac.ed@nsfnet-relay.ac.uk
Edinburgh University.                UUCP:  ...!ukc!ed.ac.uk!R.Tobin

henry@zoo.toronto.edu (Henry Spencer) (11/16/90)

In article <RJC.90Nov15073451@brodie.uk.ac.ed.cstr> rjc@uk.ac.ed.cstr (Richard Caley) writes:
>Does the standard demand that the bit pattern for then integer 0 be
>`all zeros'...

The standard demands that integer types use a "pure binary numeration
system", which is nailed down in detail in another ANSI standard.

Of course, an implementation can do whatever it pleases provided that the
observable behavior is identical to what the standard calls for.  This
includes the bit patterns written to files, however.
-- 
"I don't *want* to be normal!"         | Henry Spencer at U of Toronto Zoology
"Not to worry."                        |  henry@zoo.toronto.edu   utzoo!henry

gwyn@smoke.brl.mil (Doug Gwyn) (11/16/90)

In article <AbEJW8e00VQfE4N0I3@andrew.cmu.edu> jl57+@andrew.cmu.edu (Jay Laefer) writes:
>I realize that the following assignments are equal:
>char *fred;
>fred = 0;
>fred = (char *)NULL;
>because the compiler is responsible for translating the zero bit pattern
>into its internal representation of NULL.

They are both valid ways to assign a null pointer value to "fred", but
NOT bacuse of anthing to do with all-zero bit patterns.  In fact both
0 and NULL is such contexts stand in for a null pointer constant, which
need not have an all-zero bit representation.  That's right -- the "0"
in the above code is NOT an integer, even though it "looks" like one.

>But, given that bzero() directly fills an area with zeros, can I assume
>that the following is equivalent to the above?
>bzero(fred, sizeof (char *))

No, indeed this would try to fill "fred" with zero bits, which may not
be the right way to represent a null pointer (it depends on the
implementation).

gwyn@smoke.brl.mil (Doug Gwyn) (11/16/90)

In article <RJC.90Nov15073451@brodie.uk.ac.ed.cstr> rjc@uk.ac.ed.cstr (Richard Caley) writes:
>In article <1990Nov15.000129.27402@Think.COM> barmar@think.com (Barry Margolin) writes:
>    Bzero can only be expected to work as expected
>    when the first argument is a pointer to an integral type.
>Just as a perverse question inspired by too much bad coffee, is this
>the case?

Yes, or to an aggregate whose (possibly recursive) scalar members are
all of integral type.

>Does the standard demand that the bit pattern for then integer 0 be
>`all zeros'.

Yup, or at least it is required to be indistinguishable from such a
representation so far as a strictly conforming program could determine.

djones@megatest.UUCP (Dave Jones) (11/22/90)

From article <3764@skye.ed.ac.uk), by richard@aiai.ed.ac.uk (Richard Tobin):
) In article <RJC.90Nov15073451@brodie.uk.ac.ed.cstr) rjc@uk.ac.ed.cstr (Richard Caley) writes:
))Does the standard demand that the bit pattern for then integer 0 be
))`all zeros'.
) 
) 3.1.2.5 (Types):
)   [ "Blah blah blah blah blah," omited. ]
) 
) The intention is to allow 2s and 1s complement.

Makes you wonder why the hell they didn't say that, doesn't it?
I think standards committees must take courses in wind-production.