Description
Is it UB to change a non-mut
non-UnsafeCell
extern
static
, outside of Rust land?
Obviously it is UB to change it from Rust, but is it UB to change it from other. But is it UB to also change it from external code?
For instance, is the following UB?
Rust:
extern "C" {
static foo: i32;
fn black_box();
}
pub unsafe fn do_work() -> bool {
let a = foo;
black_box();
let b = foo;
a == b
}
C:
int32_t foo = 0;
void black_box() {
foo++;
}
LLVM does not optimize the return value of do_work()
to be true
(https://godbolt.org/z/xdqGM839n), and we also don't tell it it is constant (we say @foo = external global i32
). So this probably isn't UB from LLVM. But still, is it UB in the Rust AM?
The Reference does not hint in any way that this might be UB. It says the following about external static
s:
Statics within external blocks are declared in the same way as statics outside of external blocks,
except that they do not have an expression initializing their value.
It isunsafe
to access a static item declared in an extern block, whether or
not it's mutable, because there is nothing guaranteeing that the bit pattern at the static's
memory is valid for the type it is declared with, since some arbitrary (e.g. C) code is in charge
of initializing the static.Extern statics can be either immutable or mutable just like statics outside of external blocks.
An immutable static must be initialized before any Rust code is executed. It is not enough for
the static to be initialized before Rust code reads from it.