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

二reinterpret_cast严格混淆现象

齐建安
2023-03-14

这是一个典型的严格混叠违规示例:

std::uint32_t foo(float* f, std::uint32_t* i) {
    *i = 1;
    *f = 2;
    return *i;
}

int main() {
    std::uint32_t i = 3;
    foo(reinterpret_cast<float*>(&i), &i);
}

但假设我们添加第二reinterpret_cast

static_assert(alignof(float) == alignof(std::uint32_t));

std::uint32_t foo(float* f, std::uint32_t* i) {
    *i = 1;
    *reinterpret_cast<std::uint32_t*>(f) = 2;
    return *i;
}

int main() {
    std::uint32_t i = 3;
    std::uint32_t j = foo(reinterpret_cast<float*>(&i), &i);
    assert(j == 2);
}

这段代码正确吗(不调用未定义的行为)?

标准[expr.reinterpret.cast]如下:

注意:将“指针到<code>T1</code>”类型的prvalue转换为“指针到 和<code>T2是对象类型,并且<code>T2的对齐要求不比<code>T 1

我们使用 std::uint32_t* 类型的原始指针值来访问 std::uint32_t 类型。

当优化打开时,GCC和Clang都会生成正确的汇编代码:

foo(float*, unsigned int*):
        mov     dword ptr [rsi], 1
        mov     dword ptr [rdi], 2
        mov     eax, dword ptr [rsi]
        ret

共有1个答案

郭业
2023-03-14

以下是相应的规范文本expr.static_cast/13:

类型“指向 cv1 void 的指针”的 prvalue 可以转换为类型为“指向 cv2 T”的 prvalue,其中 T 是对象类型,cv2 是与 cv1 相同的 cv 限定或大于 cv1 的 cv 限定。如果原始指针值表示内存中某个字节的地址 A,并且 A 不满足 T 的对齐要求,则生成的指针值未指定。否则,如果原始指针值指向对象 a,并且存在一个类型为 T 的对象 b(忽略 cv 限定),该对象可与 a 进行指针互转换,则结果为指向 b 的指针。否则,指针值将因转换而保持不变。

(此文本涉及,因为在这种情况下,reinterpret_cast

因此,如果符合对齐要求,则没有任何转换(uint32_t-

 类似资料:
  • 让我们考虑以下(简化)代码来读取二进制文件的内容: 在我看来,下面一行: 包含未定义的行为:我们正在读取类型的成员,它覆盖在对象的数组之上,并且编译器可以自由地假设对象不别名。 问题是:我的解释正确吗?如果是,可以做什么来修复此代码?如果没有,为什么这里没有UB? 注1:我理解严格别名规则的目的(允许编译器避免不必要的内存加载)。此外,我知道在这种情况下,使用<code>std::memcpy</

  • 下面的getValue()成员函数是否违反了c严格别名规则? 根据该标准,我认为setValue()违反了严格的混淆现象,因为Double既不是聚合类型,也不是IEEE754_64的基类。 getValue()呢?当数据成员采用位字段形式时,它是否是一种未定义的行为,如下例所示? 我正在一个大型项目中使用类似的代码。GCC-O2和-O3输出错误值。如果我添加-fno严格的别名,问题就不存在了。此外

  • 我不知道为什么下面的代码运行得很好,没有< code>gcc错误(< code >-f strict-aliasing-Wstrict-aliasing = 1 )。 如果我遵循严格的别名规则: n1570,§6.5表达式 对象的存储值只能由具有以下类型之一的左值表达式访问: -与对象的有效类型兼容的类型, — 与对象的有效类型兼容的类型的限定版本, -与对象的有效类型对应的有符号或无符号类型的类

  • 在这些注释中,user @Deduplicator坚持认为,如果别名指针或别名指针是指向字符的指针类型(限定或非限定,有符号或无符号< code>char *),则严格的别名规则允许通过不兼容的类型进行访问。所以,他的观点基本上是 和 符合并具有定义的行为。 然而,在我看来,只有第一种形式是有效的,即当别名指针是指向char的指针时;然而,在另一个方向上却不能,即当别名指针指向不兼容的类型(而不是

  • 我一直在摆弄Proguard配置,我想测试只是为了优化 但我仍然会遇到这样的错误: java.lang.IllegalArgumentExc0019:找不到[org/apache/log/log4j/core/jackson/Log4jXmlMoules](有1个已知的超级类)和[org/apache/log/log4j/core/jackson/Log4jJsonMoules](有4个已知的超级

  • Powershell的混淆目前已经使用的越来越多,国内外也有了较多的研究,在今年的BH大会上也有对应的议题,关注点是反混淆,那么里面的一些姿势很值得我们学习,我们提供一些混淆实例,来让大家对于PS的混淆做到一个初步了解,也为防御混淆提供一些思路。 实例 在混淆之前,先看看powershell编码执行的方式。 -EC,-EncodedCommand,-EncodedComman,-EncodedCo