O Rustnomicon contém o seguinte exemplo:
#[no_mangle]
extern "C" fn assert_nonzero(input: u32) {
assert!(input != 0)
}
Se
assert_nonzero
for chamado com o argumento0
, é garantido que o tempo de execução aborte (com segurança) o processo, compilado ou não companic=abort
.
A Referência Rust, por outro lado, afirma que:
Comportamento considerado indefinido: [...] Chamar uma função com a ABI de chamada errada ou desenrolar de uma função com a ABI de desenrolar errada.
Estas duas afirmações parecem-me contraditórias. assert_nonzero
tem o C
ABI, mas relaxa com o pânico da Rust. Então, isso é garantido para abortar (com segurança) ou UB ? Não pode ser ambos.
Chayim Friedman gentilmente sugeriu em outra questão que este é realmente o UB.
Então o Rustnomicon está simplesmente desatualizado ou estou entendendo mal alguma coisa?
De forma mais geral: exatamente quando um pânico de Rust cruzando um limite FFI é considerado um comportamento indefinido?
Da RFC para
-unwind
ABIs :Parece que costumava ser UB, mas depois que essa RFC foi aceita, não é mais UB e é garantido que será abortado.
Não sei se podemos dizer que a referência está desatualizada, pois podemos dizer que simplesmente não relaxamos (mas abortamos) em caso de pânico das
extern "C"
funções Rust.