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

锈迹中的严格别名?

段弘和
2023-03-14

我的理解是,由于所谓的“严格混淆现象规则”,以下代码在C中具有未定义的行为。

#include <cstdint>

enum Foo : int16_t {};

void test(Foo& foo) {
    reinterpret_cast<int16_t&>(foo) = 42;
}

特别是,C编译器可能会完全忽略赋值,因为它可以假定int16\t

我的问题是,Rust是否有类似于C“严格混淆现象规则”的东西?换句话说,下面等效的Rust代码是否有未定义的行为?

#[repr(i16)]
enum Foo { Dummy }

unsafe fn test(foo: &mut Foo) {
    *std::mem::transmute::<&mut Foo, &mut i16>(foo) = 42;
}

编辑:
上面的示例代码有一个不相关的问题,test创建了一个不存在的枚举变量。下面是相同的代码和一个快速修复:

#[repr(i16)]
enum Foo { Dummy, Yummy = 42 }

unsafe fn test(foo: &mut Foo) {
    *std::mem::transmute::<&mut Foo, &mut i16>(foo) = 42;
}

共有1个答案

陶唯
2023-03-14
匿名用户

我的理解是,一般的Rust代码(经编译器验证)当然不包含未定义的行为(除非编译器错误),并且Rust the语言不定义任何未定义的行为,不像C。

那么,自然地,唯一可能发生未定义行为的地方就是不安全的块或函数<代码>不安全块旨在将任何潜在的危险行为封装为整体安全。2014年7月的一篇帖子提到,Rust的编译器要求满足某些不变量,并且通常破坏这些不变量是危险的,即使是在不安全的块中(实际上,只有在不安全的块中才可能破坏)。

这些危险行为之一是指针别名(这似乎是在LLVM本身中定义的)。然而,有趣的是,LLVM文档说(我的重点):

因此,基于类型的别名分析,又名TBAA,又名-fstrit-混淆现象,不适用于一般朴素的LLVM IR

因此,一般来说,只要不安全块没有触发任何其他不安全行为,严格的别名在Rust中就不是问题。

尽管如此,您的具体示例可能是危险的,因为它似乎与参考中的一种不安全行为相匹配:

基元类型中的值无效,即使是在私有字段/局部变量中:

  • 类型定义中未包含的枚举中的判别式

我为您的示例编写了一个小扩展,显示了在不安全操作之前和之后,枚举变量的二进制表示:http://is.gd/x0K9kN

如您所见,将42分配给枚举值与任何定义的鉴别器值都不匹配。但是,如果您将01分配给枚举值(或者为枚举变体定义了显式鉴别器),那么理论上操作应该没问题。

 类似资料:
  • 下面的Rust代码试图在一个数组中存储一个零参数闭包,并调用函数。 链接到 Rust Playground。不幸的是,它不会编译: 错误[E0277]:

  • 我正在阅读关于reinterpret_cast的笔记,它是混淆现象(http://en.cppreference.com/w/cpp/language/reinterpret_cast)。 我写了代码: 我认为这些规则在这里不适用: T2是对象的(可能是cv限定的)动态类型 T2和T1都是指向相同类型T3的指针(可能是多级的,可能在每个级别都是cv限定的)(因为C11) T2是一个聚合类型或并集类

  • 基本上,当启用严格别名时,此代码是否合法? 这里,我们通过另一种类型的指针(指向<code>void*</code>的指针)访问一种类型(<code<int*</code>)的对象,因此我认为这确实是一种严格的别名冲突。 但是,试图突出未定义行为的样本使我怀疑(即使它不能证明它是合法的)。 首先,如果我们将<code>int*</code>和<code>char*</code>别名,我们可以根据优

  • 我试图理解C和C的严格别名规则。我已经问了很多关于这个问题的问题,并做了一些阅读,但我只想澄清一些事情。 指向任何类型的指针都可以别名void*,这就是为什么我们可以这样做: 但是: (问题1)任何指针类型都可以别名char指针吗? 问题2:此外,当将任何指针类型别名为char或void指针类型时,我们需要确保正确的对齐方式,对吗?在堆栈上不能保证char或char数组在我们从新或malloc获得

  • ES的几个重要版本 ES5 : 09年发布。 ES6(ES2015) : 2015年发布,也称为ECMA2015。 ES7(ES2016) : 2016年发布,也称为ECMA2016 (变化不大)。 严格模式的理解 概念 理解:除了正常运行模式(混杂模式),ES5添加了第二种运行模式:"严格模式"(strict mode)。 顾名思义,这种模式使得Javascript在更严格的语法条件下运行。 目

  • 问题内容: 我知道这个问题应该在scipy.optimize手册中处理,但是我不太了解。也许你可以帮忙 我有一个函数(这只是一个示例,不是真正的函数,但是我需要在这个级别上理解它): 编辑(更好的示例): 假设我有一个矩阵 具有目标功能 现在,我想假设t [i]是实数,并且类似 问题答案: 这个约束 将是等式()约束,其中您必须创建一个必须等​​于零的函数: 然后,您对约束进行了定义(字典列表(如