[...]
Don't assume your code is safe just because it doesn't crash. When
malloc(0) returns a non-null value, the only part of the returned memory
you can portably assume is writeble is the very first byte in that block.
That's "portable" in the sense of "likely to work," not in the
sense of "guaranteed to work." The Standard does not require that
the zero-byte allocation be writable or even readable. If such an
attempt is made the behavior is undefined:
7.22.3p1: "If the size of the space requested is zero, [...]
the returned pointer shall not be used to access an object."
I'd forgotten about that clause when I wrote the above paragraph. The
clause that I was thinking about corresponds to the "..." in the above
citation, so I really had no very good excuse for thinking about one
without the other, but that's what I did.
Is this another case of "trust the programmer"? The word "shall"
implies that there is some kind of enforcement of this section. Is the
compiler/runtime required to disallow access of a zero sized object or
is the programmer required to guard against it?
There's only one circumstance in which the standard mandates rejection
of a program: if it contains a correctly formated #error directive that
survives conditional compilation.
ISO has no enforcement arm, no authority to create one. A false claim of
conformance to the C standard might be legally actionable in many
countries, but no more so than any other kind of false advertising.
The standard is, in effect, a contract. It never prohibits anything - it
just specifies what a conforming implementation of C is (and is not)
required to do when asked to translate and execute a program. An
implementation isn't prohibited from violating those requirements, it
just fails to be conforming if it does so. A program can have syntax
errors, constraint violations, or undefined behavior, but you're not
prohibited from writing such code. It's a bad idea to write such code,
but not because it's prohibited - its simply because the standard
doesn't guarantee that such code will do what you want it to do.
A program that violates a "shall" that occurs in a normative section of
the C standard, but outside of a constraint section (as is the case
here) has undefined behavior. That means the C standard imposes no
requirements of any kind on how a conforming implementation may deal
with it. Therefore, if there is anything, anything at all, that you
don't want your program to do, then you should not write such code,
because it's possible, at least in principle, that your program will do
one of the things you don't want it to do.