Skip to content

C2Rust drops attribute((destructor)) semantics, causing missing cleanup execution #1803

@rikki322

Description

@rikki322

C2Rust does not preserve the behavior of functions annotated with attribute((destructor)).
In C, a function marked with attribute((destructor)) is automatically executed after main returns or when the program exits normally. However, the translated Rust code does not register or invoke the destructor function, so the cleanup logic is omitted from the program behavior.
This causes a semantic mismatch between the original C program and the translated Rust program.
To Reproduce

#include <stdio.h>

static int x = 0;

__attribute__((destructor))
static void cleanup(void) {
    x = 1;
    printf("destructor called, x=%d\n", x);
}

int main(void) {
    printf("main, x=%d\n", x);
    return 0;
}

Translate the program with C2Rust:

c2rust transpile compile_commands.json

C2Rust generates code:

#![allow(
    dead_code,
    non_camel_case_types,
    non_snake_case,
    non_upper_case_globals,
    unused_assignments,
    unused_mut
)]
extern "C" {
    fn printf(__format: *const ::core::ffi::c_char, ...) -> ::core::ffi::c_int;
}

static mut x: ::core::ffi::c_int = 0 as ::core::ffi::c_int;

unsafe fn main_0() -> ::core::ffi::c_int {
    printf(b"main, x=%d\n\0" as *const u8 as *const ::core::ffi::c_char, x);
    return 0 as ::core::ffi::c_int;
}

pub fn main() {
    unsafe { ::std::process::exit(main_0() as i32) }
}

Observed Behavior
Original C output:

main, x=0
destructor called, x=1

Translated Rust output:

main, x=0

The cleanup function is not preserved or invoked in the translated Rust program.
Environment

  • c2rust version: v0.21.0
  • platform: Ubuntu 24.04
  • Rust: nightly-2022-08-08
  • Clang version: 17.0.6

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions