c – 使用强制转换为“错误”类型的指针算法

c – 使用强制转换为“错误”类型的指针算法,第1张

概述我有一个结构数组,我有一个指向其中一个结构的成员的指针.我想知道数组的哪个元素包含该成员.这有两种方法: #include <array>#include <string>struct xyz{ float x, y; std::string name;};typedef std::array<xyz, 3> triangle;// return which ve @H_301_1@我有一个结构数组,我有一个指向其中一个结构的成员的指针.我想知道数组的哪个元素包含该成员.这有两种方法:
#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 ofint 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 01 1 1 12 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    ,%rax    imulq   %rsi,%raxvertex_b(std::array<xyz,float const*):    subq    %rdi,%rsi    movabsq $-3689348814741910323,%rdx ; 0xCCC...CD    movq    %rsi,%rax    mulq    %rdx    movq    %rdx,%rax    shrq    ,%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 – 使用强制转换为“错误”类型的指针算法全部内容,希望文章能够帮你解决c – 使用强制转换为“错误”类型的指针算法所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1242642.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存