[PATCH v2 3/4] Say malloc (0) != NULL is now common; resection
Paul Eggert
eggert@cs.ucla.edu
Thu Feb 12 20:35:23 GMT 2026
On 2/12/26 10:28, DJ Delorie wrote:
> An application that can accept more than one
> implementation's definition has been ported, but is not portable. Yes,
> posix defines two possible behaviors, but still leaves the non-null
> returned pointer's access undefined.
Not sure what is meant here by the distinction between "ported" and
"portable", given that there are only two possible behaviors.
For example, the following toy program works with both glibc malloc
(which has one behavior) and IBM AIX malloc (which has the other). And
the program works even if N happens to be zero and the program calls
malloc (0). Is this program "portable"? Is it "ported"? What's the
practical difference between the two notions here?
#include <stdlib.h>
int
main ()
{
size_t n = rand ();
unsigned char *p = malloc (n);
if (!p && n)
return 2;
for (size_t i = 0; i < n; i++)
p[i] = rand ();
unsigned int chksum = 0;
for (size_t i = 0; i < n; i++)
chksum ^= p[i];
return chksum != 0;
}
> To fully avoid undefined or implementation-defined behavior, a portable
> program should avoid this completely by never passing zero to malloc.
Typically, the manual shouldn't advise people to avoid all
implementation-defined behavior. (If it did that, it'd have to say
"Never call 'rand'."...) Instead, it should document when behavior is
implementation-defined and let people make up their own minds.
There may be cases where an implementation-defined behavior is so
dangerous that it is invariably counterproductive and the manual should
advise against using it. I'm not sure that is the case here, though.
More information about the Libc-alpha
mailing list