gpt4 book ai didi

c++ - 这种类型的双关语定义明确吗?

转载 作者:太空狗 更新时间:2023-10-29 20:54:48 26 4
gpt4 key购买 nike

阅读 this answer 中的引述关于严格的别名规则,我在 C++11 中看到以下内容:

If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined:

  • ...

  • an aggregate or union type that includes one of the aforementioned types among its elements or non-static data members (including, recursively, an element or non-static data member of a subaggregate or contained union),

  • ...

所以我认为下面的代码没有违反严格的别名规则:

#include <iostream>
#include <cstdint>
#include <climits>
#include <limits>

struct PunnerToUInt32
{
std::uint32_t ui32;
float fl;
};

int main()
{
static_assert(std::numeric_limits<float>::is_iec559 &&
sizeof(float)==4 && CHAR_BIT==8,"Oops");
float x;
std::uint32_t* p_x_as_uint32=&reinterpret_cast<PunnerToUInt32*>(&x)->ui32;
*p_x_as_uint32=5;
std::cout << x << "\n";
}

好的,满足严格的别名规则。由于任何其他原因,这是否仍然表现出未定义的行为?

最佳答案

你不能这样做:&reinterpret_cast<PunnerToUInt32*>(&x)

关于 reinterpret_cast 的规则状态:

When a pointer or reference to object whose dynamic type is DynamicType is reinterpret_cast (or C-style cast) to a pointer or reference to object of a different type AliasedType, the cast always succeeds, but the resulting pointer or reference may only be used to access the object if one of the following is true:

  • AliasedType is (possibly cv-qualified) DynamicType
  • AliasedType and DynamicType are both (possibly multi-level, possibly cv-qualified at each level) pointers to the same type T
  • AliasedType is the (possibly cv-qualified) signed or unsigned variant of DynamicType
  • AliasedType is an aggregate type or a union type which holds one of the aforementioned types as an element or non-static member (including, recursively, elements of subaggregates and non-static data members of the contained unions): this makes it safe to obtain a usable pointer to a struct or union given a pointer to its non-static member or element.
  • AliasedType is a (possibly cv-qualified) base class of DynamicType
  • AliasedType is char or unsigned char: this permits examination of the object representation of any object as an array of unsigned char

因为这些都不适用于 DynamicType 的组合正在floatAliasedType正在PunnerToUInt32该指针不能用于访问您正在执行的对象。使行为未定义。

有关详细信息,请参阅:Why Doesn't reinterpret_cast Force copy_n for Casts between Same-Sized Types?

编辑:

分解第 4th 个子弹 int 大小块产量:

  1. "AliasedType "
    此处取为PunnerToUInt32
  2. “是聚合类型还是 union 类型”
    PunnerToUInt32合格,因为它符合 aggregate type 的资格:

    • array type
    • class type (typically, struct or union), that has
      • no private or protected non-static data members
      • no user-provided constructors, including those inherited from public bases (explicitly defaulted or deleted constructors are allowed)
      • no virtual, private, or protected base classes
      • no virtual member functions
  3. “将上述类型之一作为元素或非静态成员(递归地包括子聚合的元素和包含的 union 的非静态数据成员)”
    再次 PunnerToUInt32符合条件,因为它是 float fl成员

  4. “这使得获取指向结构或 union 的可用指针变得安全”
    这是最后的正确部分 AliassedTypePunnerToUInt32
  5. “给定一个指向其非静态成员或元素的指针”
    这是一个违规行为,因为 DynamicType这是 x不是 PunnerToUInt32 的成员

因为违反第​​ 5 部分操作这个指针是未定义的行为。

如果您喜欢一些推荐读物,可以查看 Empty Base Optimization如果不是,我会在此处为您提供主要相关性:

Empty base optimization is required for StandardLayoutTypes in order to maintain the requirement that the pointer to a standard-layout object, converted using reinterpret_cast, points to its initial member

因此你可以利用reinterpret_cast这样做的第 4 个 项目符号:

PunnerToUInt32 x = {13, 42.0F};
auto y = reinterpret_cast<PunnerToUInt32*>(&x.ui32);

Live Example

关于c++ - 这种类型的双关语定义明确吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38000599/

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