代码之家  ›  专栏  ›  技术社区  ›  ChrisB

Rust FFI边界上的恐慌是什么时候?未定义行为?

  •  1
  • ChrisB  · 技术社区  · 2 年前

    这个 rustnomicon 包含以下示例:

    #[no_mangle]
    extern "C" fn assert_nonzero(input: u32) {
        assert!(input != 0)
    }
    

    如果 assert_nonzero 与参数一起调用 0 ,保证运行时(安全地)中止进程,无论是否使用编译 panic=abort .


    这个 Rust Reference 另一方面声称:

    被认为未定义的行为:[…]用错误的调用ABI调用函数,或用错误的展开ABI从函数展开。


    这两种说法在我看来是矛盾的。 assert_nonzero 具有 C ABI,但从Rust恐慌中解脱出来。那是吗 保证(安全地)中止 ,或 UB ? 不可能两者都有。

    Chayim Friedman善意地建议 another question 这确实是UB。

    那么,乡村经济学只是过时了,还是我误解了什么?

    更一般地说: Rust恐慌跨越外国金融机构边界究竟何时被视为未定义行为?

    1 回复  |  直到 2 年前
        1
  •  2
  •   Chayim Friedman    2 年前

    发件人 the RFC for -unwind ABIs :

    对现有ABI字符串行为的更改

    在此RFC之前,任何跨越 extern "C" 边界,从 panic! 从Rust函数“转义” 定义为 外部“C” 或者通过从另一种语言输入Rust 通过用声明的入口点 外部“C” ,导致未定义 行为。

    这个RFC保留了大部分未定义的行为,只有一个例外: 与 panic=unwind 运行时, 恐慌! 将导致 abort 如果 否则会从用定义的函数中“转义” 外部“C” .

    此更改将应用于除 "Rust" , 例如 "system" .

    所以看起来这曾经是UB,但在这个RFC被接受后,它不再是UB,并保证会中止。

    我不知道我们是否可以说这个参考已经过时了,因为我们可以说我们只是没有放松(但放弃)来自 外部“C” Rust函数。

    推荐文章