C 中两个不同类型的不同变量的地址可以比较吗?

问题描述 投票:0回答:1

我很难理解 C 中严格别名的一个方面。

据我了解,不兼容类型的指针不能相互转换。但是,在将这些不同类型转换为

void*
char*
,甚至转换为它们的数字表示形式之后,如何比较这些不同类型之间的指针比较呢?

在 C 中,(比方说 C23)以下断言得到保证吗?

int x = 1;
float y = 1.0f;

assert((void*)(&x) != (void*)(&y)); // always passes?
assert((char*)(&x) != (char*)(&y)); // always passes?

// something like a "reinterpret cast" to uint64_t
// or another type that is correct for some system
assert((uint64_t)(&x) != (uint64_t)(&y)); // always passes?

我为什么问:这两个变量的位置是否允许在数值上(或其他方面)相等?例如,浮点数可能存储在某种“浮点内存”中,而 int 可能存储在某些具有相同地址的“整型内存”中,但 CPU 根据类型查找 int 内存或浮点内存?

我很好奇的是,是否可以有两个不同的堆栈,例如针对不同的数据类型(假设的示例:将浮点数存储在 GPU 内存中,将整数存储在普通内存中,或者类似的东西,但是地址比较相等)那个硬件)。或者编译器是否需要将这些差异带回到比较运算符中?


我对此的发现:

  • 在6.5.9中它说“如果两个指向对象类型的指针都指向同一个对象,或者都指向 经过同一数组对象的最后一个元素,它们比较相等”。我认为这不是同一个对象,但我只看到一个方向,如果 x 然后它们比较,而不是相反。
  • 不是 C,但类似地,在 C++ 中我读到“请注意,表示相同地址的两个指针可能仍然具有不同的值。” 这里。但我缺少我的案例的例子。
  • 旧的新闻组帖子

我尝试过的:我试图让断言失败,但它们每次都有效,但我很好奇如果符合标准的编译器做了一些特殊的事情,理论上它们是否会失败

基本上,对于不兼容数据类型的指针,比较是否有意义?如果不是,尽管变量不同,它是否可以“相等”?

c pointers comparison strict-aliasing c23
1个回答
0
投票

断言总是会通过,因为你有两个变量在内存中分配了空间,它们都从尚未分配的空间中分配空间,并且当内存中的空间被分配时

y 
x
已经占据了自己的位置。

但是,不同类型的两个不同变量可以具有相同的地址,因此可能有两个不同类型的不同指针引用相同的地址。

证明:

#include <stdio.h>

int main() {
    int someint = 123;
    int *a = &someint;
    float *b = (float *)a;
    printf("a is located at %p, b is located at %p", a, b);
    return 0;
}

小提琴:https://www.mycompiler.io/view/HcVk9ubiMDf

© www.soinside.com 2019 - 2024. All rights reserved.