Re: NULL and zeros



Michael Mair wrote:
Yevgen Muntyan wrote:

Richard Heathfield wrote:

Christopher Layne said:

Richard Heathfield wrote:

[defensive programming yadda yadda]


I meant it is *implied* and was not written because it wasn't relevant to the discussion at hand.


I understood what you meant by "implied", and my previous answer to that point remains valid IMHO.

You clipped my last segment.


Oops.

If a machine expressed integer 0 as all 1 bits internally, and I called
memset(&object, 0, sizeof(object)); that's going to result in object set
to all 0 bits?


Yes, it must. The machine's bizarre internal representation does not excuse the implementation from its obligations. The semantics of memset(&object, 0, sizeof(object)) is "starting at the address indicated by object, set sizeof(object) bytes to the value (unsigned char)0". If object has integer type then that process must have the effect of setting object's value to 0. If it has some other type, however, there is no such requirement.


Standard says in 7.20.3.1: "The calloc function allocates space for an array of nmemb objects, each of whose size
is size. The space is initialized to all bits zero."
It looks like "starting at the address indicated by object, set
> sizeof(object) bytes to the value (unsigned char)0" is your own
interpretation caused by the knowledge of real world computers and
compilers :)


No, unsigned char is _guaranteed_ to have no padding bits. In addition,
it is an unsigned integer type, so the representation of
(unsigned char)0 indeed is "one byte with all bits 0".
So, Richard described it equivalently using his knowledge of the
standard.

Indeed, I was tricked by that wording and inferred that his words imply
that Standard guarantees that

int *a;
int i;
char c = 0;
for (i = 0; i < sizeof (a); ++i)
memcpy (((char*)&a) + i, &c, 1);

is equivalent to

int *a;
memset (&a, 0, sizeof (a))

(or analogous thing with calloc()). What Richard said was indeed
"butter is made of butter", since standard says "all zero bits",
and it says the same about (char)0, and there is no way you can
actually *set* all *bytes* in a structure to (unsigned char)0. (To
that effect you can use memset, memcpy and so on, but does standard
say what it means "to set bytes to zero"?)

Anyway, this newsgroup is not comp.std.c is it?


You clearly did not bother to do your "homework", i.e. finding out
what this newsgroup considers topical. I suggest reading
http://clc-wiki.net/wiki/intro_to_clc
and especially
http://clc-wiki.net/wiki/C_community:comp.lang.c:Introduction#topical

Indeed, that says "The group deals with C only to the (narrow) extent
that the ANSI/ISO C Standard defines it.", so my question was off-topic
since I did know standard doesn't guarantee all-zero-bits NULL.

So, when I want to get some knowledge of C programmers out there,
comp.lang.c is a wrong place.

So you are playing
games with standard here; you are saying "On some machines, that isn't
the case. If you are excluding such machines, you are in the wrong newsgroup.", and it's no good. Show me chunk of real world code
which will work on any machine covered by standard; or stop pretending
C doesn't mean a programming language used in real world.


Once again: Richard's position is correct for comp.lang.c -- apart
from that, and back to your original question:
- whenever I find some calloc() in someone's code, I assume that
the originator of this calloc() is clueless -- my personal
experience points to this relationship.

Single fact that zeroing memory gives you a crash instead of random
behavior very well justifies using of calloc(), unless it's expensive
(or is there any other objection to using calloc()?).

- I prefer the "constructor" or "init element" methods for setting
up struct types that may vary during development.

I have init() methods, but they do not allocate memory, that's done
elsewhere, and I get calloc'ed structures, and so on and so forth.
Blah blah blah.
And then in my something_new() methods I like to use calloc() (actually
a wrapper around calloc which will abort if calloc() fails).

- The compiler may well optimise a malloc() call followed by a
check for NULL followed by an initialisation to effectively all
bits zero by a call to calloc() if deemed necessary.

Again, calloc call happens elsewhere, compiler has no idea about that.
And mind you, "optimise"? Holy standard knows that word? Or you just
using off-topic arguments since conversation is off-topic anyway?

- In addition, I often have entries that need not be initialised
to zero -- why have the overhead of calloc() to set the respective
bytes to all bits zero?

Overhead is how much exactly? A very simple example: when I need to
scroll in a text widget, I create a structure with some stuff inside,
like what line to scroll to and so on. "Overhead" is exactly zero.

Apart from that: It is possible to write real world programmes that
run on "virtually all" hosted implementations -- implementation limits
may make the programme fail consistently, though.
In addition, one usually strives to keep the portable part of other
programmes as large as possible and isolate non-portable parts in
a couple of headers and/or modules.

Yes, but as I said elsewhere, I am not going not to assume 8 bits
in bytes whenever it's convenient (X likes 8 bits bytes, and there
are cases where you use 8, 16, or 32 as an argument. guess what 8 is).
Of course convenience should not hurt portability. Assuming 8-bits byte
doesn't.

The question was specifically about existence of machines with certain
properties, for a real world application, not about whether standard
says yes or no about some particular thing.


There are _many_ past threads enumerating machines with null pointers
being not all bits zero. Whether you consider these machines relevant
is your decision. However, your position reads to me "I am making
non-portable assumptions but I think these are not too restrictive
and quite portable for what I want to do -- please confirm this".

Care to read the original question? Very simple. Yes, I did use words
like "do I care", sorry for that, next time I will try to use more
robot language.

Without giving us _all_ the data for a well-founded expert placet to
this. The only possible answer can be "it is not portable, so this
practice is ill-advised".

Well, if you really are willing to help and need _all_ the data, you
could for start simply tell if there's a machine with X with NULL not
being all zero bits; as far as I understand there's none.
Come on, you care about absolute portability, great. But why tell all
this great stuff about this and that when the question was indeed
simple (I actually thought that there is a strange platform with X
where NULL might not be all zero bits, sorry for not admitting my
stupidity and asking you to forgive me at the very beginning)?

Regards,
Yevgen
.


Quantcast