Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
Deewiant opened this issue Mar 2, 2018 · 2 comments
Open

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

Deewiant opened this issue Mar 2, 2018 · 2 comments

Comments

@Deewiant
Copy link

Deewiant commented Mar 2, 2018

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.

@emilio
Copy link
Contributor

emilio commented Mar 2, 2018

The clang constant evaluation stuff doesn't work for arrays at all afaict, so this would need upstream changes to libclang to be fixable.

@Deewiant
Copy link
Author

Deewiant commented Mar 2, 2018

You're right. I filed it upstream: https://bugs.llvm.org/show_bug.cgi?id=36576

Otherwise, I suppose #297 would provide a fix, but it's a bigger undertaking.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants