相关疑难解决方法(0)

添加到"char*"指针UB,当它实际上没有指向char数组?

C++ 17(expr.add/4)说:

当向指针添加或从指针中减去具有整数类型的表达式时,结果具有指针操作数的类型.如果表达式P指向具有n个元素的数组对象x的元素x [i],则表达式P + J和J + P(其中J具有值j)指向(可能是假设的)元素x [i + j]如果0≤i+j≤n; 否则,行为未定义.同样地,如果0≤i-j≤n,则表达式P-J指向(可能是假设的)元素x [i-j]; 否则,行为未定义.

struct Foo {
    float x, y, z;
};

Foo f;
char *p = reinterpret_cast<char*>(&f) + offsetof(Foo, z); // (*)
*reinterpret_cast<float*>(p) = 42.0f;
Run Code Online (Sandbox Code Playgroud)

该行标有(*)UB?reinterpret_cast<char*>(&f)不指向char数组,而是指向浮点数,因此根据引用的段落它应该是UB.但是,如果它是UB,那么它offsetof的用处将是有限的.

是UB吗?如果没有,为什么不呢?

c++ language-lawyer

12
推荐指数
3
解决办法
392
查看次数

c++11 严格别名规则是否允许通过 char *、char(&amp;)[N]、甚至 std::array&lt;char, N&gt;&amp; 和 -fstrict-aliasing -Wstrict-aliasing=2 访问 uint64_t?

根据有关C++11/14严格别名规则的stackoverflow答案:

如果程序尝试通过以下类型之一以外的泛左值访问对象的存储值,则行为未定义:

  • 对象的动态类型,

  • 对象动态类型的 cv 限定版本,

  • 与对象的动态类型类似的类型(如 4.4 中定义),
  • 与对象的动态类型相对应的有符号或无符号类型,
  • 与对象动态类型的 cv 限定版本相对应的有符号或无符号类型,
  • 聚合或联合类型,其元素或非静态数据成员中包括上述类型之一(递归地包括子聚合或包含的联合的元素或非静态数据成员),
  • 是对象动态类型的(可能是 cv 限定的)基类类型的类型,
  • acharunsigned char类型。

我们可以使用以下方式访问其他类型的存储吗

(1)char *

(2)char(&)[N]

(3)std::array<char, N> &

不依赖于未定义的行为

constexpr uint64_t lil_endian = 0x65'6e'64'69'61'6e; 
    // a.k.a. Clockwise-Rotated Endian which allocates like
    // char[8] = { n,a,i,d,n,e,\0,\0 }

const auto& arr =   // std::array<char,8> &
    reinterpret_cast<const std::array<char,8> &> (lil_endian);

const auto& carr =  // char(&)[8]>
    reinterpret_cast<const char(&)[8]>           (lil_endian);

const auto* …
Run Code Online (Sandbox Code Playgroud)

c++ strict-aliasing language-lawyer c++11

5
推荐指数
1
解决办法
380
查看次数

标签 统计

c++ ×2

language-lawyer ×2

c++11 ×1

strict-aliasing ×1