调用memmove或memcpy是否定义了NULL?

时间:2014-03-07 22:35:48

标签: c standards c99 memcpy memmove

我刚刚在我的设置(gcc 4.8.2,最近的uClibc)上测试了以下内容,它运行良好:

#include <string.h>
int main(int argc, char **argv) {
    char buf[4], fub[4] = "abc";
    memmove(buf, fub, 0);
    memmove(buf, NULL, 0);
    memmove(NULL, fub, 0);
    memmove(NULL, NULL, 0);
    return 0;
}

它也适用于memcpy。所以很明显,将NULL传递给这些函数在实践中可行,至少在某些设置上。但是我想要进行防御性编码,并且我正在尝试确定是否有任何C标准允许我依赖来处理此行为,或者是否未定义或实现定义。

This answer指出C99标准确实规定将大小0传递给这些函数应该是有效的。以下是第7.21.1节中的文字:

  

如果声明为size_t n的参数指定了函数数组的长度,则在调用该函数时,n的值可以为零。除非在本子条款中对特定函数的描述中另有明确说明,否则此类调用上的指针参数仍应具有有效值,如7.1.4中所述。在这样的调用中,找到一个字符的函数找不到,一个比较两个字符序列的函数返回零,一个复制字符的函数复制零个字符。

另一方面,阅读第7.1.4节似乎说没有定义传递NULL

  

除非在以下详细说明中另有明确说明,否则以下每个陈述都适用:如果函数的参数具有无效值(例如函数域外的值,或者地址空间外的指针)程序,或空指针,或指向不可修改的存储的指针,当相应的参数不是const限定的)或类型(提升后)不具有可变数量的参数的函数,行为是未定义的。< / p>

这也是你的理解吗?任何人都可以确认/否认标准是否未定义此行为?

我主要针对C99,但也欢迎有关其他C标准的反馈。

0 个答案:

没有答案