memcpy 将零字节写入 const 变量 - 未定义的行为?

Jac*_*lan 36 c c++ constants memcpy language-lawyer

在C和C++中,当要复制的字节数为零时,memcpy进入变量是否是未定义的行为?const

int x = 0;
const int foo = 0;
memcpy( (void *)&foo, &x, 0 );
Run Code Online (Sandbox Code Playgroud)

这个问题并不纯粹是理论上的。我有一个场景,其中memcpy被调用,如果目标指针指向const内存,则大小参数保证为零。所以我想知道是否需要将其作为特殊情况处理。

Nat*_*dge 38

老问题是否保证执行 memcpy(0,0,0) 是安全的?指出7.1.4p1:

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

的原型memcpy

void *memcpy(void * restrict s1, const void * restrict s2, size_t n);
Run Code Online (Sandbox Code Playgroud)

其中第一个参数没有const- 限定,并&foo指向不可修改的存储。所以这段代码是 UB 的,除非memcpy另有明确说明,但事实并非如此。它只是说:

memcpy 函数将 s2 指向的对象中的 n 个字符复制到 s1 指向的对象中。

这意味着memcpycount0不会复制任何字符(7.24.1p2“复制零个字符”也证实了这一点,感谢 Lundin),但它并不能免除您传递有效参数的要求。

  • 由于 C++ 并没有放松对 C 库的要求,因此对于 C++ 来说也是如此。 (6认同)
  • 我怀疑这将是一个Shroedinger's bug - 绝对没有理由以您描述的方式调用它会导致任何问题;但是一旦你真正实现它,你就会发现世界上只有一个库在你这样做时崩溃了,而且它就是你正在使用的库。 (6认同)