Skip to content

Definitions of static or macro-defined arrays are not emitted #1266

Open
@Deewiant

Description

@Deewiant

Input C Header

#define MACRO_ARRAY {1, 2}

static const int static_const_array[] = {3, 4};

Bindgen Invocation

$ bindgen input.h

Actual Results

extern "C" {
    #[link_name = "\u{1}static_const_array"]
    pub static mut static_const_array: [::std::os::raw::c_int; 2usize];
}

(The presence of the mut is #511, it's not the point of this issue but I'm just noting that that's a separate incorrect thing here.)

Expected Results

As it is, neither array can be used with bindgen alone. MACRO_ARRAY is not emitted and attempting to use static_const_array will result in a link error, because there is no definition, only a declaration.

I was hoping to see at least:

static static_const_array: [::std::os::raw::c_int; 2usize] = [3, 4];

And ideally:

// Inferred as c_int based on the types of 1 and 2
static MACRO_ARRAY: [::std::os::raw::c_int; 2usize] = [1, 2];

static static_const_array: [::std::os::raw::c_int; 2usize] = [3, 4];

I figure that cases like MACRO_ARRAY are difficult in general, relating to issues like #316. But if at least the static_const_array case would work, it could be used as a simple workaround for the macro support.

Workaround

As it is, one has to write and compile some C (typically involving the cc crate) that provides a symbol to hold the array value, and in the non-macro case a way of initializing it because C can't do it at compile time. For example:

#include <string.h>
#define MACRO_ARRAY {1, 2}
static const int static_const_array[] = {3, 4};

const int my_macro_array[] = MACRO_ARRAY;

int my_static_const_array[sizeof(static_const_array) / sizeof(static_const_array[0])];
void my_static_const_array_init(void) {
   memcpy(my_static_const_array, static_const_array, sizeof static_const_array);
}

And then in the bindgen stub declare e.g.:

const int my_macro_array[sizeof((int[])MACRO_ARRAY) / sizeof(int)] = MACRO_ARRAY;

extern int my_static_const_array[sizeof(static_const_array) / sizeof(static_const_array[0])];
extern void my_static_const_array_init(void);

And finally, arrange a way of calling my_static_const_array_init when needed.

Needless to say, this is quite painful. :-) I'm open to better approaches, this is just the most straightforward thing off the top of my head.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions