On Mon, Dec 31, 2012 at 10:21:09AM +0000, David Laight wrote: > > > Modified Files: > > > src/lib/libutil: efun.c > > > > > > Log Message: > > > If malloc, calloc, or realloc returns NULL when a size of 0 was > > > requested, which is allowed by pertinent standards, honor it instead > > > of bombing. > > > > > > Do not do this for calloc(x, y) where x != 0 && y != 0 but x*y == 0; > > > in that case bomb. > > > > The commit message is misleading. We expect calloc(x,y) to return NULL > > if x!=0 && y!=0 && x*y==0. > > I've never quite understood why calloc() was ever defined with 2 > parameters.
Me either. > The only time it can be different (and valid) from a naiive multiply > is when the multiply is done as 'int' on a system where size_t > int. It does mean that the overflow test is centralized instead of being replicated at every allocation site, which has its virtues. > I'd have thought calloc() should be required to check that the > multiply doesn't overflow - but that ought (probably) require a different > errno than ENOMEM. This is not explicitly stated in C99, but from the wording it is certainly *allowed* to check, and one could construct a reasonable argument that it's required to. > Certainly checking for multiply overflow would seem better than > checking for the product being zero. Yes. But, you know, I didn't change calloc, I changed ecalloc. The question is when a NULL return is an error. It is not an error if a size of zero is requested, but it is on overflow. A size of zero is requested only if one or both of the arguments is zero, *not* if the product is zero. Hence the logic I described. TBH, I don't understand why this is apparently confusing. -- David A. Holland dholl...@netbsd.org