rust-lang / rust-lang/rust-bindgen
Definitions of static or macro-defined arrays are not emitted
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 5.3k
- Forks
- 829
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 15
Description
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.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the bindgen input.h case containing MACRO_ARRAY and static_const_array, then inspect how the invocation emits the shown Rust declarations. Compare the generated output with the expected array definitions and determine what completion should cover for static arrays versus macro-defined arrays; the issue provides no specific source file or test path.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, rust
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100