I used c2rust to translate the following C code to Rust
#include <stdint.h>
#include <stdio.h>
static int32_t a[1];
static int32_t *b = &a[0];
int main() {
*b = 1;
printf("%d\n", a[0]);
}
The generated result is
#![allow(dead_code, mutable_transmutes, non_camel_case_types, non_snake_case, non_upper_case_globals, unused_assignments, unused_mut)]
use ::c2rust_generated::*;
extern "C" {
fn printf(_: *const libc::c_char, _: ...) -> libc::c_int;
}
pub type __int32_t = libc::c_int;
pub type int32_t = __int32_t;
static mut a: [int32_t; 1] = [0; 1];
static mut b: *mut int32_t = 0 as *const int32_t as *mut int32_t;
unsafe fn main_0() -> libc::c_int {
*b = 1 as libc::c_int;
printf(b"%d\n\0" as *const u8 as *const libc::c_char, a[0 as libc::c_int as usize]);
return 0;
}
pub fn main() {
unsafe { ::std::process::exit(main_0() as i32) }
}
unsafe extern "C" fn run_static_initializers() {
b = &mut *a.as_mut_ptr().offset(0 as libc::c_int as isize) as *mut int32_t;
}
#[used]
#[cfg_attr(target_os = "linux", link_section = ".init_array")]
#[cfg_attr(target_os = "windows", link_section = ".CRT$XIB")]
#[cfg_attr(target_os = "macos", link_section = "__DATA,__mod_init_func")]
static INIT_ARRAY: [unsafe extern "C" fn(); 1] = [run_static_initializers];
It's worth noting that building wasm32-wasi and i686-unknown-linux-gnu, their execution results are not the same.
$ cargo build --target wasm32-wasi
$ cargo build --target i686-unknown-linux-gnu
It should be noted that the reason for this difference is that when built to wasm32-wasi, run_static_initializers is not executed (which can be found by adding log in that function). Is there any approach similar to the INIT_ARRAY in this code to ensure that run_static_initializers is executed before the main function when built to wasm32-wasi?