Path: csiph.com!eternal-september.org!feeder.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: UB of memcpy(NULL, NULL, 0) Date: Mon, 17 Oct 2016 11:21:22 -0700 Organization: None to speak of Lines: 49 Message-ID: References: <58034cbc.2767375@news.xs4all.nl> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Injection-Info: mx02.eternal-september.org; posting-host="5cf263897792072a9f2f11bacfc4852d"; logging-data="13575"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19YLJAehghh6Qha2+082HYG" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) Cancel-Lock: sha1:WyapPoGHk1SMnwUe9MpsIeEF90c= sha1:c/uMrV8UVgZj9VxjIJoYB6fjvQo= Xref: csiph.com comp.lang.c:95007 supercat@casperkitty.com writes: [...] > I don't think anyone is arguing that if memcpy is given a *non-zero length* > it should not require both pointers to be valid. If the length is zero, > however, the Standard specifies no reason why memcpy should do *anything* > with its other arguments. While it might be possible for an implementation > to achieve the indicated behavior by checking for a null argument, I would > not expect any implementation would use null-argument checking for that > purpose rather than simply exiting early in the case where length is zero. Your argument is based on what the standard says. What it says, unambiguously, is that the behavior of memcpy() is undefined if either s1 or s1 is null. It doesn't give a *reason* for memcpy(NULL, 0, 0) to do anything because it doesn't need to. It doesn't give reasons for most of its rules. *Should* memcpy(NULL, NULL, 0) have been well defined (similar to the way free(NULL) is well defined)? Maybe. Given a choice, I might have had a slight preference for defining it to do nothing. But I wasn't given that choice, and I'm fine with that. I would oppose changing it to be well defined in a future standard, because the transition could cause more problems than the current rule and it would be more difficult to explain. And consider compiler warnings. Suppose a compiler is able to prove that the s1 and/or s2 argument is a null pointer, but doesn't know whether n is zero. A contrived example: $ gcc-6.2.0 -c -Wnonnull c.c c.c: In function ‘main’: c.c:4:5: warning: null argument where non-null required (argument 1) [-Wnonnull] memcpy(NULL, NULL, rand() % 2); ^~~~~~ c.c:4:5: warning: null argument where non-null required (argument 2) [-Wnonnull] $ If memcpy(NULL, NULL, 0) were well defined, the warning would have to be considerably more verbose. As far as I'm concerned, it's just not that big a deal. The current rule seems to be optimized for simplicity. -- Keith Thompson (The_Other_Keith) kst-u@mib.org Working, but not speaking, for JetHead Development, Inc. "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister"