C在转换后的指针上的相等运算符 [英] C's equality operator on converted pointers

查看:133
本文介绍了C在转换后的指针上的相等运算符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

来自将整数常量转换为指针类型

从这个问题中,我们从6.3.2.3p5(C11)知道我们可以将任何整数转换为指针(即它本身不是UB):

From that question, we know from 6.3.2.3p5 (C11) that we can convert any integer into a pointer (i.e. it is not UB on itself):

整数可以转换为任何指针类型.除非先前指定,否则结果是实现定义的,可能未正确对齐,可能未指向引用类型的实体,并且可能是陷阱表示.

An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation.

然后,从6.5.9p6开始,我们有:

Then, from 6.5.9p6, we have:

当且仅当两个都是空指针时,两个指针比较相等,两个都是指向同一个对象的指针(包括指向对象和它的开始处的子对象的指针)或函数,两者都是指向最后一个元素的指针相同的数组对象,或者一个是指向一个数组对象末尾的指针,另一个是指向另一个数组对象的起点的指针,而该数组对象恰好紧随地址空间中的第一个数组对象.

Two pointers compare equal if and only if both are null pointers, both are pointers to the same object (including a pointer to an object and a subobject at its beginning) or function, both are pointers to one past the last element of the same array object, or one is a pointer to one past the end of one array object and the other is a pointer to the start of a different array object that happens to immediately follow the first array object in the address space.

因此,似乎我们可以在没有UB的情况下应用相等运算符(与关系运算符不同).考虑:

So it seems we can apply the equality operator here with no UB (unlike the relational operators). Consider:

struct A;

int f(void) {
    struct A * a = (struct A *) 1;
    struct A * b = (struct A *) 1;
    return a == b;
}

假设a的地址1中没有A对象,则可能会争辩说f()应该返回false,因为没有条件与上面的条件匹配.

Assuming there is no A object in a's address 1, one could argue that f() should return false, because no condition matches the above.

这是如何被驳斥的?即使没有对象,指向同一对象的指针"是否也指向地址(无论如何也不是编译器所知道的)?我们是否应该简单地理解它是实现定义的,因为先前的结果已经是实现定义的?标准在哪里指定?

How is this refuted? Does "pointer to the same object" refer to addresses, even if no objects are there (not like the compiler could know, anyway)? Should we simply understand that it is implementation-defined since the previous results were already implementation-defined? Where does the standard specify this?

所有主流编译器都会如预期那样返回上述代码的true.

All major compilers return true for the above code, as one would expect.

推荐答案

这是如何被驳斥的? 指向相同对象的指针"是否指 地址,即使没有对象

How is this refuted? Does "pointer to the same object" refer to addresses, even if no objects are there

不,我认为这不是看似合理的读法.如果您规定指针值不是指向对象的指针(并且它不是空指针),则该(指针)值与其自身的相等比较不满足6.5.9/的仅当"条件6,因此比较值必须为0.

No, I don't think that would be a plausible reading. If you stipulate that the pointer value is not a pointer to an object (and if it is not a null pointer) then an equality comparison of that (pointer) value with itself does not satisfy the "only if" condition of 6.5.9/6, and therefore the comparison must evaluate to 0.

但是不是那么快.谁说(struct A *) 1不是指向对象的指针? 考虑标准对对象"的定义:

But not so fast. Who says that (struct A *) 1 is not a pointer to an object? Consider the Standard's definition of "object":

对象
执行环境中数据存储区域的内容 可以代表值

object
region of data storage in the execution environment, the contents of which can represent values

( C 2011,3.15/1 )

请注意,定义并不固有地限于程序分配或声明的对象.就我所知,该标准无处以这种方式限制该术语的范围.它确实定义了分配对象的方法,但是没有指定以那些方式之一分配的对象是唯一存在的对象.因此,实现可以自由地将指针值解释为指向对象的指针,在这种情况下,相等比较的结果可能为1.

Note that the definition is not inherently limited to objects that are allocated or declared by the program. To the best of my knowledge, the standard nowhere limits the scope of the term in that way. It does define means to allocate objects, but it does not specify that objects allocated in one of those ways are the only ones that exist. Thus, implementations are free to interpret that pointer value as a pointer to an object, in which case the equality comparison may evaluate to 1.

它仍然可能求值为1,因为尽管两个指针(大概)具有按位表示形式,但不一定将它们视为指向同一对象的指针.

It also might still not evaluate to 1, as despite the two pointers (presumably) having bitwise-identical representations, they are not necessarily considered pointers to the same object.

(不像编译器可以 知道吗?)

(not like the compiler could know, anyway)?

当然,编译器可以并且应该知道.它必须知道以便评估诸如您所呈现的表达式.最直接的方法(并非巧合的是,最常见的方法)是将每个不是陷阱表示形式的非空指针值解释为指向对象的指针.

Of course the compiler could and should know. It has to know in order to evaluate expressions such as you present. The most straightforward approach -- and, not coincidentally, the most common -- is to interpret every non-null pointer value that is not a trap representation as a pointer to an object.

我们应该简单地了解它是 实施定义,因为先前的结果已经存在 实现定义的?

Should we simply understand that it is implementation-defined since the previous results were already implementation-defined?

被实现定义的需求要求符合实现以记录其选择.您要询问的行为可能来自将整数转换为指针的实现定义的行为,但它本身不是实现定义的.

Being implementation-defined carries a requirement for conforming implementations to document their choice. The behavior you're asking about may follow from the implementation-defined behavior of converting an integer to a pointer, but it is not implementation-defined itself.

标准在哪里指定?

Where does the standard specify this?

未指定.原则上,在这一点上一致的实现可能会有所不同.但是在实践中,它们是非常一致的.

It does not specify. In principle, conforming implementations may differ on this point. In practice, however, they're pretty consistent.

这篇关于C在转换后的指针上的相等运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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