当前位置: 首页 > 知识库问答 >
问题:

通过std::bit_cast()ed指针进行别名访问

华知
2023-03-14

违反严格别名规则会产生未定义的行为,例如,当通过网络将结构发送到char缓冲区时,然后该char指针被C-style/< code > STD::reinterpret _ cast()强制转换为结构指针。

Cstd::bit_cast()函数看起来可以用于以(实现?)定义的方式转换此类指针,即不违反严格的混淆现象规则。

示例:

#include <sys/types.h>
#include <netinet/in.h>

#include <bit>

int get_sock_addr(const struct sockaddr *a)
{
    struct sockaddr_in *x = std::bit_cast<struct sockaddr_in*>(a);
    return x->sin_addr.s_addr;
}

因此,get_sock_addr()的调用方以某种方式获得了一个sockaddr指针,并确定它实际上指向一个sockaddr_instruct。

那么,通过 std::bit_cast() 进行此类指针转换是有效的用例吗?

还是它也会产生未定义的行为?

如果是定义的行为,标准是否将这种指针强制转换归类为实现定义的行为?

标准::bit_cast()提案提到:

如果没有值表示对应于to的对象表示,则返回的值是未指定的。

那么,如果不同的指针表示不兼容,以致它们不能相互对应,那么符合标准的编译器是可能的吗?

共有1个答案

林华皓
2023-03-14

转换指针值无关紧要。重要的是对象。您有一个指向X类型对象的指针,但该指针的类型是Y。试图通过指向不相关类型Y的指针/引用访问X类型对象是UB的来源。

您如何获得这些指针大多无关紧要。因此,在这方面,bit_cast并不比reinterpret_cast好。

如果那里没有sockaddr_in,那么你不能假装有。然而,在C 20中隐式对象创建可能已经解决了这个问题,这取决于你的代码。如果是这样,那么你如何获得指针仍然无关紧要。

 类似资料:
  • 我有以下C/C代码(编译器浏览器链接): 在clang和gcc编译为C或至少启用了的情况下,上述代码转换为此程序集: 对于add,它似乎在做一些类似于: 但是对于乘法,它正在做: 为什么乘法在加法上需要额外的指令,或者它不是必需的,只是更快?

  • 下面是一个示例: 我一直认为它定义得很好(否则的意义是什么),但我不确定。 最近我被告知它实际上是UB,所以我想一劳永逸地弄清楚它。 上面的例子到底有没有引起UB?如果你把类修改成非标准布局,会影响结果吗? 如果是UB,是否有任何解决方法(例如,应用< code>std::launder)? 这整个主题似乎没有实际意义,而且没有得到充分的阐述。 以下是我能够找到的一些信息: > 添加到“char*

  • 在一些遗留代码中,我遇到了以下空指针检查。 通过此if检查检查空指针是否存在技术风险?

  • 通过将函数传递给函数call by pointer方法call by pointer将参数的地址复制到形式参数中。 在函数内部,该地址用于访问调用中使用的实际参数。 这意味着对参数所做的更改会影响传递的参数。 要通过指针传递值,参数指针将像任何其他值一样传递给函数。 因此,您需要将函数参数声明为指针类型,如以下函数swap() ,该函数swap()其参数指向的两个整数变量的值。 // functi

  • 我了解如何使用Android SDK通过指纹认证来认证用户。但它只会告诉指纹是否匹配其中一个注册的指纹,即布尔值。 我想让它也给我指纹图像,这样我就可以根据指纹提取信息,比如存储在数据库中的用户名、姓名等。 例如:我有3个用户:管理员、教师、学生。我应该能够使用内置指纹读取器来确定用户是否被识别为管理员、教师或学生,并相应地授予应用程序访问权限。 该应用程序将仅部署到一个设备,所有用户都可以访问,

  • 我在一个类中使用了几个函数,这些函数通过函数接口传递给ostream,而函数接口又可以用来输出错误消息。我曾希望能够将所有ostream绑定到一个对象,然后在必要时重定向到一个文件。 我的代码的相关部分如下所示: 在构造函数(或程序中的所有构造函数)的第一个花括号中,我得到以下错误消息: 受保护功能“std::basic\u ostream 或者对于我粘贴在此处的简短示例代码: “std::bas