Lint against #[no_mangle] for non-repr(C) pub statics · Issue #11219 · rust-lang/rust-clippy (original) (raw)

What it does

The lint should lint against a #[no_mangle] pub static which has a type which is not repr(C) (or that has no explicit repr(Rust) set).

This would be similar to no_mangle_with_rust_abi from #10347, but for pub statics.

Advantage

Avoids potential subtle mistakes and UB in programs that mix Rust and other languages like C: one cannot predict the layout of repr(Rust) types and thus an exported static marked with #[no_mangle] has a high chance of being a mistake.

Drawbacks

No response

Example

pub struct S(u8, u16);

#[no_mangle] pub static X: S = S(0xFF, 0xFFFF);

Should be written as:

#[repr(C)] pub struct S(u8, u16);

#[no_mangle] pub static X: S = S(0xFF, 0xFFFF);

Otherwise, a C program with manually written bindings (e.g. projects not using cbindgen, which in this case would generate an incomplete type) trying to access X will break sooner or later, potentially silently (using -Zrandomize-layout would increase the chances of the issue being spotted, though), e.g.

#include <assert.h> #include <stdint.h>

struct S { uint8_t a; uint16_t b; };

extern const struct S X;

int main(void) { assert(X.a == 0xFF); assert(X.b == 0xFFFF); return 0; }