C&C++   发布时间:2022-04-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了c – 使用强制转换为“错误”类型的指针算法大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个结构数组,我有一个指向其中一个结构的成员的指针.我想知道数组的哪个元素包含该成员.这有两种方法
#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,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

但你不能从指向xyz :: y的指针转换为指向xyz的指针.该操作未定义.

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

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

大佬总结

以上是大佬教程为你收集整理的c – 使用强制转换为“错误”类型的指针算法全部内容,希望文章能够帮你解决c – 使用强制转换为“错误”类型的指针算法所遇到的程序开发问题。

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

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。