[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