是否在C11中定义了memcpy(& a + 1,& b + 1,0)? [英] Is memcpy(&a + 1, &b + 1, 0) defined in C11?

查看:164
本文介绍了是否在C11中定义了memcpy(& a + 1,& b + 1,0)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此问题遵循上一个问题关于memcpy(0, 0, 0)的定义,该结论已被确定为未定义的行为.

This question follows this previous question about the definedness of memcpy(0, 0, 0), which has been conclusively determined to be undefined behavior.

如链接的问题所示,答案取决于C11条款7.1.4:1的内容

As the linked question shows, the answer hinges on the contents of C11's clause 7.1.4:1

除非以下声明中另有明确说明,否则以下每个语句均适用:如果函数的参数具有无效值(例如,函数域之外的值,或者指针的地址空间之外的指针),程序或空指针[[]])[…]行为未定义. […]

Each of the following statements applies unless explicitly stated otherwise in the detailed descriptions that follow: If an argument to a function has an invalid value (such as a value outside the domain of the function, or a pointer outside the address space of the program, or a null pointer, […]) […] the behavior is undefined. […]

标准函数memcpy()期望指向voidconst void的指针,如下所示:

The standard function memcpy() expects pointers to void and const void, as so:

void *memcpy(void * restrict s1, const void * restrict s2, size_t n);

这个问题完全值得一问,因为标准中有两个有效"指针的概念:存在可以通过指针算术有效获得并可以与<指向同一对象内的其他指针.并且有一些可用于取消引用的指针.前一类在随后的代码段中包含过去"指针,例如&a + 1&b + 1,而后一类则不包括这些指针.

The question is worth asking at at all only because there are two notions of "valid" pointers in the standard: there are the pointers that can validly be obtained through pointer arithmetics and can validly be compared with <, > to other pointers inside the same object. And there are pointers that are valid for dereferencing. The former class includes "one-past" pointers such as &a + 1 and &b + 1 in the following snippet, whereas the latter class does not include these as valid.

char a;
const char b = '7';
memcpy(&a + 1, &b + 1, 0);

鉴于memcpy()的自变量无论如何都应作为指向void的指针,因此应将上述代码段视为已定义的行为,因此它们各自的有效性问题不在于解引用它们.还是应该将&a + 1&b + 1视为程序的地址空间之外"?

Should the above snippet be considered defined behavior, in light of the fact that the arguments of memcpy() are typed as pointers to void anyway, so the question of their respective validities cannot be about dereferencing them. Or should &a + 1 and &b + 1 be considered "outside the address space of the program"?

这对我很重要,因为我正在规范标准C函数的效果.我已经将memcpy()的一个前提条件写为requires \valid(s1+(0 .. n-1));,直到有人指出我的注意为止,GCC 4.9已经开始积极地优化上述库函数的调用,使其超出上述公式中表示的范围(

This matters to me because I am in the process of formalizing the effects of standard C functions. I had written one pre-condition of memcpy() as requires \valid(s1+(0 .. n-1));,until it was pointed to my attention that GCC 4.9 had started to aggressively optimize such library function calls beyond what is expressed in the formula above (indeed). The formula \valid(s1+(0 .. n-1)) in this particular specification language is equivalent to true when n is 0, and does not capture the undefined behavior that GCC 4.9 relies on to optimize.

推荐答案

C11说:

(C11,7.24.2.1p2)"memcpy函数将s2指向的对象中的n个字符复制到s1指向的对象中."

(C11, 7.24.2.1p2) "The memcpy function copies n characters from the object pointed to by s2 into the object pointed to by s1."

&a + 1本身是指向整数加法的有效指针,但&a + 1并非指向对象的指针,因此该调用会调用未定义的行为.

&a + 1 itself is a valid pointer to integer addition but &a + 1 is not a pointer to an object, so the call invokes undefined behavior.

这篇关于是否在C11中定义了memcpy(&amp; a + 1,&amp; b + 1,0)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆