从我系统的手册页:
void*memmove(void*dst,const void*src,size_t len);
描述
memmove()函数将字符串src中的len个字节复制到字符串dst.
两个字符串可能重叠 ; 副本总是以非破坏性的
方式完成.
从C99标准:
6.5.8.5比较两个指针时,结果取决于指向的对象的地址空间中的相对位置.如果指向对象或不完整类型的两个指针都指向同一个对象,或者两个指针都指向同一个数组对象的最后一个元素,则它们相等.如果指向的对象是同一聚合对象的成员,则指向稍后声明的结构成员的指针比指向结构中先前声明的成员的指针大,指向具有较大下标值的数组元素的指针比指向同一数组的元素的指针大.具有较低的下标值.指向同一个union对象的成员的所有指针都比较相等.如果表达
P指向数组对象的元素,表达式Q指向同一数组对象的最后一个元素,指针表达式Q+1比较大于P.在所有其他情况下,行为 未定义.
重点是我的.
的参数dst和src可被转化为指针char以便减轻严格别名的问题,但有可能以比较两个指针可以指向内部的不同的块,以便做以正确的顺序的拷贝的情况下,它们指向相同的块内?
显而易见的解决方案是if (src < dst),但未定义如果src和dst指向不同的块."未定义"意味着您甚至不应该假设条件返回0或1(这在标准词汇表中称为"未指定").
另一种选择是if ((uintptr_t)src < (uintptr_t)dst),至少是未指定的,但我不确定标准是否保证何时src < dst定义,它等同于(uintptr_t)src < (uintptr_t)dst).指针比较是从指针算法定义的.例如,当我在添加时阅读第6.5.6节时,在我看来,指针算法可以与uintptr_t算术相反的方向,即兼容的编译器可能具有,当p类型为char*:
((uintptr_t)p)+1==((uintptr_t)(p-1)
Run Code Online (Sandbox Code Playgroud)
这只是一个例子.一般来说,将指针转换为整数时,似乎可以保证很少.
这是一个纯粹的学术问题,因为memmove它与编译器一起提供.在实践中,编译器作者可以简单地将未定义的指针比较提升为未指定的行为,或者使用相关的编译指示强制其编译器memmove正确编译它们.例如,此实现具有以下代码段:
if ((uintptr_t)dst < (uintptr_t)src) {
/*
* As author/maintainer of libc, take advantage …Run Code Online (Sandbox Code Playgroud) 我最近在回答一个关于p < q当p和q是指向不同对象/数组的指针时在C 中执行的未定义行为的问题。这让我想到:C ++ <在这种情况下具有相同(未定义)的行为,但是还提供了标准库模板std::less,该模板保证可以返回与<可以比较指针时相同的东西,并在不能比较时返回一些一致的顺序。
C是否提供具有类似功能的东西,从而可以安全地比较任意指针(相同类型)?我尝试浏览C11标准并没有发现任何东西,但是我在C中的经验比在C ++中小得多,因此我很容易错过一些东西。
c pointers memory-model undefined-behavior memory-segmentation
问题:如果指针比较等于,它们的整数转换值也等于吗?
例如:
void *ptr1 = //...
void *ptr2 = //...
printf("%d", ptr1 == ptr2); //prints 1
Run Code Online (Sandbox Code Playgroud)
这是否意味着(intptr_t) ptr1 == (intptr_t) ptr2也1?
从务实的角度来看应该是正确的。但是考虑标准在7.20.1.4(p1)以下方面指定的内容:
以下类型指定了一个带符号的整数类型,其属性是
void可以将任何有效指针都转换为该类型,然后再转换回到的指针void,结果将与原始指针进行比较:Run Code Online (Sandbox Code Playgroud)intptr_t
它与实现可以将相同的指针转换为不同的值(取决于某些奇怪的情况)并不矛盾,这保留了转换回的值产生相同的指针。
因此,我认为不,比较相等的指针的整数转换值不必彼此相等。