gpt4 book ai didi

c++ - 使用转换为 "wrong"类型的指针算法

转载 作者:可可西里 更新时间:2023-11-01 18:15:42 27 4
gpt4 key购买 nike

我有一个结构数组,并且有一个指向其中一个结构的成员 的指针。我想知道数组的哪个元素包含该成员。这里有两种方法:

#include <array>
#include <string>

struct xyz
{
float x, y;
std::string name;
};

typedef std::array<xyz, 3> triangle;

// return which vertex the given coordinate is part of
int vertex_a(const triangle& tri, const float* coord)
{
return reinterpret_cast<const xyz*>(coord) - tri.data();
}

int vertex_b(const triangle& tri, const float* coord)
{
std::ptrdiff_t offset = reinterpret_cast<const char*>(coord) - reinterpret_cast<const char*>(tri.data());
return offset / sizeof(xyz);
}

这是一个测试驱动程序:

#include <iostream>

int main()
{
triangle tri{{{12.3, 45.6}, {7.89, 0.12}, {34.5, 6.78}}};
for (const xyz& coord : tri) {
std::cout
<< vertex_a(tri, &coord.x) << ' '
<< vertex_b(tri, &coord.x) << ' '
<< vertex_a(tri, &coord.y) << ' '
<< vertex_b(tri, &coord.y) << '\n';
}
}

两种方法都产生了预期的结果:

0 0 0 0
1 1 1 1
2 2 2 2

但它们是有效代码吗?

特别是我想知道 vertex_a() 是否可能通过将 float* y 转换为 xyz* 来调用未定义的行为,因为结果不是实际上指向一个struct xyz。这种担忧促使我编写了 vertex_b(),我认为这是安全的(是吗?)。

这是 GCC 6.3 使用 -O3 生成的代码:

vertex_a(std::array<xyz, 3ul> const&, float const*):
movq %rsi, %rax
movabsq $-3689348814741910323, %rsi ; 0xCCC...CD
subq %rdi, %rax
sarq $3, %rax
imulq %rsi, %rax

vertex_b(std::array<xyz, 3ul> const&, float const*):
subq %rdi, %rsi
movabsq $-3689348814741910323, %rdx ; 0xCCC...CD
movq %rsi, %rax
mulq %rdx
movq %rdx, %rax
shrq $5, %rax

最佳答案

根据标准,两者均无效。


vertex_a 中,您可以将指向 xyz::x 的指针转换为指向 xyz 的指针,因为它们是 pointer-interconvertible :

Two objects a and b are pointer-interconvertible if [...] one is a standard-layout class object and the other is the first non-static data member of that object [...]

If two objects are pointer-interconvertible, then they have the same address, and it is possible to obtain a pointer to one from a pointer to the other via a reinterpret_­cast.

但是您不能将指向 xyz::y 的指针转换为指向 xyz 的指针。该操作未定义。


vertex_b 中,您要减去两个指向 const char 的指针。该操作在 [expr.add] 中定义为:

If the expressions P and Q point to, respectively, elements x[i] and x[j] of the same array object x, the expression P - Q has the value i − j; otherwise, the behavior is undefined

您的表达式不指向 char 数组的元素,因此行为未定义。

关于c++ - 使用转换为 "wrong"类型的指针算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44409207/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com