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

Bad bindings for empty C struct on windows #1683

Open
colindr opened this issue Nov 20, 2019 · 5 comments
Open

Bad bindings for empty C struct on windows #1683

colindr opened this issue Nov 20, 2019 · 5 comments
Labels

Comments

@colindr
Copy link

colindr commented Nov 20, 2019

Input C Header

struct mystruct {
};

Bindgen Invocation

This is specifically for windows. I've installed LLVM according to the documentation, and I'm setting my LIBCLANG_PATH like so (in powershell):

$env:LIBCLANG_PATH="C:\Program Files\LLVM\bin\"

Then I invoke bindgen like so:

bindgen test.h  -o src/bindings.rs

Actual Results

/* automatically generated by rust-bindgen */

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct mystruct {
    pub _address: u8,
}
#[test]
fn bindgen_test_layout_mystruct() {
    assert_eq!(
        ::std::mem::size_of::<mystruct>(),
        4usize,
        concat!("Size of: ", stringify!(mystruct))
    );
    assert_eq!(
        ::std::mem::align_of::<mystruct>(),
        1usize,
        concat!("Alignment of ", stringify!(mystruct))
    );
}

Expected Results

I expected it to generate an empty rust struct, like so:

/* automatically generated by rust-bindgen */

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct mystruct {}
#[test]
fn bindgen_test_layout_mystruct() {
    assert_eq!(
        ::std::mem::size_of::<mystruct>(),
        0usize,
        concat!("Size of: ", stringify!(mystruct))
    );
    assert_eq!(
        ::std::mem::align_of::<mystruct>(),
        1usize,
        concat!("Alignment of ", stringify!(mystruct))
    );
}

From this issue I understand that the
_address field is supposed to be added for C++ structs, but this is a C struct. Also, the tests
that are generated are incorrect, the u8 _address field is 1usize not 4usize.

I've tested this on linux and it's not a problem there.

Here are the debugging logs:

[2019-11-20T23:44:04Z INFO  bindgen] Clang Version: clang version 8.0.1 (tags/RELEASE_801/final)
[2019-11-20T23:44:04Z WARN  bindgen] Using clang (8, 0), expected (3, 9)
[2019-11-20T23:44:04Z DEBUG bindgen] Generating bindings, libclang at C:\Program Files\LLVM\bin\libclang.dll
[2019-11-20T23:44:04Z DEBUG bindgen] Trying to find clang with flags: []
[2019-11-20T23:44:05Z DEBUG bindgen] Found clang: Clang { path: "C:\\Program Files\\LLVM\\bin\\clang.exe", version: Some(CXVersion { Major: 8, Minor: 0, Subminor: 1 }), c_search_paths: Some(["C:\\Program Files\\LLVM\\lib\\clang\\8.0.1\\include", "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Professional\\VC\\Tools\\MSVC\\14.23.28105\\include", "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.18362.0\\ucrt", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\shared", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\um", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\winrt"]), cpp_search_paths: Some(["C:\\Program Files\\LLVM\\lib\\clang\\8.0.1\\include", "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Professional\\VC\\Tools\\MSVC\\14.23.28105\\include", "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.18362.0\\ucrt", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\shared", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\um", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\winrt"]) }
[2019-11-20T23:44:05Z DEBUG bindgen] Fixed-up options: BindgenOptions { blacklisted_types: RegexSet { items: [], matched: [], set: Some(RegexSet([])), record_matches: true }, blacklisted_functions: RegexSet { items: [], matched: [], set: Some(RegexSet([])), record_matches: true }, blacklisted_items: RegexSet { items: [], matched: [], set: Some(RegexSet([])), record_matches: true }, opaque_types: RegexSet { items: [], matched: [], set: Some(RegexSet([])), record_matches: true }, rustfmt_path: None, whitelisted_types: RegexSet { items: [], matched: [], set: Some(RegexSet([])), record_matches: true }, whitelisted_functions: RegexSet { items: [], matched: [], set: Some(RegexSet([])), record_matches: true }, whitelisted_vars: RegexSet { items: [], matched: [], set: Some(RegexSet([])), record_matches: true }, default_enum_style: Consts, bitfield_enums: RegexSet { items: [], matched: [], set: Some(RegexSet([])), record_matches: true }, rustified_enums: RegexSet { items: [], matched: [], set: Some(RegexSet([])), record_matches: true }, rustified_non_exhaustive_enums: RegexSet { items: [], matched: [], set: None, record_matches: false }, constified_enum_modules: RegexSet { items: [], matched: [], set: Some(RegexSet([])), record_matches: true }, constified_enums: RegexSet { items: [], matched: [], set: Some(RegexSet([])), record_matches: true }, builtins: false, emit_ast: false, emit_ir: false, emit_ir_graphviz: None, enable_cxx_namespaces: false, enable_function_attribute_detection: false, disable_name_namespacing: false, layout_tests: true, impl_debug: false, impl_partialeq: false, derive_copy: true, derive_debug: true, derive_default: false, derive_hash: false, derive_partialord: false, derive_ord: false, derive_partialeq: false, derive_eq: false, use_core: false, ctypes_prefix: None, time_phases: false, namespaced_constants: true, msvc_mangling: false, convert_floats: true, raw_lines: [], module_lines: {}, clang_args: ["-isystem", "C:\\Program Files\\LLVM\\lib\\clang\\8.0.1\\include", "-isystem", "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Professional\\VC\\Tools\\MSVC\\14.23.28105\\include", "-isystem", "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.18362.0\\ucrt", "-isystem", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\shared", "-isystem", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\um", "-isystem", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\winrt", "test.h"], input_header: Some("test.h"), input_unsaved_files: [], parse_callbacks: None, codegen_config: FUNCTIONS | TYPES | VARS | METHODS | CONSTRUCTORS | DESTRUCTORS, conservative_inline_namespaces: false, generate_comments: true, generate_inline_functions: false, whitelist_recursively: true, objc_extern_crate: false, generate_block: false, block_extern_crate: false, enable_mangling: true, detect_include_paths: true, prepend_enum_name: true, rust_target: Stable_1_33, rust_features: RustFeatures { untagged_union: true, associated_const: true, builtin_clone_impls: true, repr_align: true, i128_and_u128: true, must_use_function: true, repr_transparent: true, min_const_fn: true, repr_packed_n: true, thiscall_abi: false, non_exhaustive: false }, record_matches: true, rustfmt_bindings: true, rustfmt_configuration_file: None, no_partialeq_types: RegexSet { items: [], matched: [], set: Some(RegexSet([])), record_matches: true }, no_copy_types: RegexSet { items: [], matched: [], set: Some(RegexSet([])), record_matches: true }, no_hash_types: RegexSet { items: [], matched: [], set: Some(RegexSet([])), record_matches: true }, array_pointers_in_arguments: false }
[2019-11-20T23:44:05Z DEBUG bindgen::ir::item] Item::from_ty_with_id: ItemId(1)
        ty = Type(struct mystruct, kind: Record, cconv: 100, decl: Cursor(mystruct kind: StructDecl, loc: test.h:1:8, usr: Some("c:@S@mystruct")), canon: Cursor(mystruct kind: StructDecl, loc: test.h:1:8, usr: Some("c:@S@mystruct"))),
        location = Cursor(mystruct kind: StructDecl, loc: test.h:1:8, usr: Some("c:@S@mystruct"))
[2019-11-20T23:44:05Z DEBUG bindgen::ir::context] builtin_or_resolved_ty: Type(struct mystruct, kind: Record, cconv: 100, decl: Cursor(mystruct kind: StructDecl, loc: test.h:1:8, usr: Some("c:@S@mystruct")), canon: Cursor(mystruct kind: StructDecl, loc: test.h:1:8, usr: Some("c:@S@mystruct"))), Some(Cursor(mystruct kind: StructDecl, loc: test.h:1:8, usr: Some("c:@S@mystruct"))), Some(ItemId(0))
[2019-11-20T23:44:05Z DEBUG bindgen::ir::context] Not resolved, maybe builtin?
[2019-11-20T23:44:05Z DEBUG bindgen::ir::context] builtin_or_resolved_ty: Type(struct mystruct, kind: Record, cconv: 100, decl: Cursor(mystruct kind: StructDecl, loc: test.h:1:8, usr: Some("c:@S@mystruct")), canon: Cursor(mystruct kind: StructDecl, loc: test.h:1:8, usr: Some("c:@S@mystruct"))), Some(Cursor(mystruct kind: StructDecl, loc: test.h:1:8, usr: Some("c:@S@mystruct"))), Some(ItemId(0))
[2019-11-20T23:44:05Z DEBUG bindgen::ir::context] Not resolved, maybe builtin?
[2019-11-20T23:44:05Z DEBUG bindgen::ir::ty] from_clang_ty: ItemId(1), ty: Type(struct mystruct, kind: Record, cconv: 100, decl: Cursor(mystruct kind: StructDecl, loc: test.h:1:8, usr: Some("c:@S@mystruct")), canon: Cursor(mystruct kind: StructDecl, loc: test.h:1:8, usr: Some("c:@S@mystruct"))), loc: Cursor(mystruct kind: StructDecl, loc: test.h:1:8, usr: Some("c:@S@mystruct"))
[2019-11-20T23:44:05Z DEBUG bindgen::ir::ty] currently_parsed_types: [PartialType { decl: Cursor(mystruct kind: StructDecl, loc: test.h:1:8, usr: Some("c:@S@mystruct")), id: ItemId(1) }]
[2019-11-20T23:44:05Z DEBUG bindgen::ir::comp] CompInfo::from_ty(Struct, Cursor(mystruct kind: StructDecl, loc: test.h:1:8, usr: Some("c:@S@mystruct")))
[2019-11-20T23:44:05Z DEBUG bindgen::ir::context] BindgenContext::add_item(Item { id: ItemId(1), local_id: Cell { value: None }, next_child_local_id: Cell { value: 1 }, canonical_name_cache: RefCell { value: None }, comment: None, annotations: Annotations { opaque: false, hide: false, use_instead_of: None, disallow_copy: false, private_fields: None, accessor_kind: None, constify_enum_variant: false, derives: [] }, parent_id: ItemId(0), kind: Type(Type { name: Some("mystruct"), layout: Some(Layout { size: 4, align: 1, packed: false }), kind: Comp(CompInfo { kind: Struct, fields: BeforeComputingBitfieldUnits([]), template_params: [], methods: [], constructors: [], destructor: None, base_members: [], inner_types: [], inner_vars: [], has_own_virtual_method: false, has_destructor: false, has_nonempty_base: false, has_non_type_template_params: false, packed_attr: false, found_unknown_attr: false, is_forward_declaration: false }), is_const: false }) }, declaration: Some(Cursor(mystruct kind: StructDecl, loc: test.h:1:8, usr: Some("c:@S@mystruct"))), loc: Some(Cursor(mystruct kind: StructDecl, loc: test.h:1:8, usr: Some("c:@S@mystruct")))
[2019-11-20T23:44:05Z DEBUG bindgen::ir::context] add_item_to_module: adding ItemId(1) as child of parent module ItemId(0)
[2019-11-20T23:44:05Z DEBUG bindgen::ir::context] No replacements to process
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::has_vtable] constrain ItemId(1)
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::has_vtable]     comp considers its own methods and bases
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::has_vtable] constrain ItemId(0)
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::sizedness] constrain TypeId(ItemId(1))
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::sizedness]     comp considers its own fields and bases
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::sizedness] inserting ZeroSized for TypeId(ItemId(1))
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::template_params] constrain ItemId(1)
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::template_params]   initially, used set is {}
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::template_params]     other item: join with successors' usage
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::template_params]   finally, used set is {}
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::template_params] constrain ItemId(0)
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::template_params]   initially, used set is {}
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::template_params]     other item: join with successors' usage
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::template_params]   finally, used set is {}
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::derive] constrain: ItemId(1)
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::derive] ty: Type { name: Some("mystruct"), layout: Some(Layout { size: 4, align: 1, packed: false }), kind: Comp(CompInfo { kind: Struct, fields: AfterComputingBitfieldUnits([]), template_params: [], methods: [], constructors: [], destructor: None, base_members: [], inner_types: [], inner_vars: [], has_own_virtual_method: false, has_destructor: false, has_nonempty_base: false, has_non_type_template_params: false, packed_attr: false, found_unknown_attr: false, is_forward_declaration: false }), is_const: false }
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::derive]     can derive Debug because there are no members
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::derive] inserting ItemId(1) can_derive<Debug>=Yes
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::derive] constrain: ItemId(0)
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::derive]     can derive Debug because there are no members
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::derive] inserting ItemId(0) can_derive<Debug>=Yes
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::derive] constrain: ItemId(1)
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::derive] ty: Type { name: Some("mystruct"), layout: Some(Layout { size: 4, align: 1, packed: false }), kind: Comp(CompInfo { kind: Struct, fields: AfterComputingBitfieldUnits([]), template_params: [], methods: [], constructors: [], destructor: None, base_members: [], inner_types: [], inner_vars: [], has_own_virtual_method: false, has_destructor: false, has_nonempty_base: false, has_non_type_template_params: false, packed_attr: false, found_unknown_attr: false, is_forward_declaration: false }), is_const: false }
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::derive]     can derive Copy because there are no members
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::derive] inserting ItemId(1) can_derive<Copy>=Yes
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::derive] constrain: ItemId(0)
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::derive]     can derive Copy because there are no members
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::derive] inserting ItemId(0) can_derive<Copy>=Yes
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::has_type_param_in_array] constrain: ItemId(1)
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::has_type_param_in_array]     comp doesn't have array
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::has_type_param_in_array] constrain: ItemId(0)
[2019-11-20T23:44:05Z TRACE bindgen::ir::analysis::has_type_param_in_array]     not a type; ignoring
[2019-11-20T23:44:05Z DEBUG bindgen::codegen] codegen: BindgenOptions { blacklisted_types: RegexSet { items: [], matched: [], set: Some(RegexSet([])), record_matches: true }, blacklisted_functions: RegexSet { items: [], matched: [], set: Some(RegexSet([])), record_matches: true }, blacklisted_items: RegexSet { items: [], matched: [], set: Some(RegexSet([])), record_matches: true }, opaque_types: RegexSet { items: [], matched: [], set: Some(RegexSet([])), record_matches: true }, rustfmt_path: None, whitelisted_types: RegexSet { items: [], matched: [], set: Some(RegexSet([])), record_matches: true }, whitelisted_functions: RegexSet { items: [], matched: [], set: Some(RegexSet([])), record_matches: true }, whitelisted_vars: RegexSet { items: [], matched: [], set: Some(RegexSet([])), record_matches: true }, default_enum_style: Consts, bitfield_enums: RegexSet { items: [], matched: [], set: Some(RegexSet([])), record_matches: true }, rustified_enums: RegexSet { items: [], matched: [], set: Some(RegexSet([])), record_matches: true }, rustified_non_exhaustive_enums: RegexSet { items: [], matched: [], set: None, record_matches: false }, constified_enum_modules: RegexSet { items: [], matched: [], set: Some(RegexSet([])), record_matches: true }, constified_enums: RegexSet { items: [], matched: [], set: Some(RegexSet([])), record_matches: true }, builtins: false, emit_ast: false, emit_ir: false, emit_ir_graphviz: None, enable_cxx_namespaces: false, enable_function_attribute_detection: false, disable_name_namespacing: false, layout_tests: true, impl_debug: false, impl_partialeq: false, derive_copy: true, derive_debug: true, derive_default: false, derive_hash: false, derive_partialord: false, derive_ord: false, derive_partialeq: false, derive_eq: false, use_core: false, ctypes_prefix: None, time_phases: false, namespaced_constants: true, msvc_mangling: false, convert_floats: true, raw_lines: [], module_lines: {}, clang_args: ["-isystem", "C:\\Program Files\\LLVM\\lib\\clang\\8.0.1\\include", "-isystem", "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Professional\\VC\\Tools\\MSVC\\14.23.28105\\include", "-isystem", "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.18362.0\\ucrt", "-isystem", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\shared", "-isystem", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\um", "-isystem", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\winrt", "test.h"], input_header: Some("test.h"), input_unsaved_files: [], parse_callbacks: None, codegen_config: FUNCTIONS | TYPES | VARS | METHODS | CONSTRUCTORS | DESTRUCTORS, conservative_inline_namespaces: false, generate_comments: true, generate_inline_functions: false, whitelist_recursively: true, objc_extern_crate: false, generate_block: false, block_extern_crate: false, enable_mangling: true, detect_include_paths: true, prepend_enum_name: true, rust_target: Stable_1_33, rust_features: RustFeatures { untagged_union: true, associated_const: true, builtin_clone_impls: true, repr_align: true, i128_and_u128: true, must_use_function: true, repr_transparent: true, min_const_fn: true, repr_packed_n: true, thiscall_abi: false, non_exhaustive: false }, record_matches: true, rustfmt_bindings: true, rustfmt_configuration_file: None, no_partialeq_types: RegexSet { items: [], matched: [], set: Some(RegexSet([])), record_matches: true }, no_copy_types: RegexSet { items: [], matched: [], set: Some(RegexSet([])), record_matches: true }, no_hash_types: RegexSet { items: [], matched: [], set: Some(RegexSet([])), record_matches: true }, array_pointers_in_arguments: false }
[2019-11-20T23:44:05Z DEBUG bindgen::codegen] <Item as CodeGenerator>::codegen: self = Item { id: ItemId(0), local_id: Cell { value: None }, next_child_local_id: Cell { value: 1 }, canonical_name_cache: RefCell { value: None }, comment: None, annotations: Annotations { opaque: false, hide: false, use_instead_of: None, disallow_copy: false, private_fields: None, accessor_kind: None, constify_enum_variant: false, derives: [] }, parent_id: ItemId(0), kind: Module(Module { name: Some("root"), kind: Normal, children: {ItemId(1)} }) }
[2019-11-20T23:44:05Z DEBUG bindgen::codegen] <Module as CodeGenerator>::codegen: item = Item { id: ItemId(0), local_id: Cell { value: None }, next_child_local_id: Cell { value: 1 }, canonical_name_cache: RefCell { value: None }, comment: None, annotations: Annotations { opaque: false, hide: false, use_instead_of: None, disallow_copy: false, private_fields: None, accessor_kind: None, constify_enum_variant: false, derives: [] }, parent_id: ItemId(0), kind: Module(Module { name: Some("root"), kind: Normal, children: {ItemId(1)} }) }
[2019-11-20T23:44:05Z DEBUG bindgen::codegen] <Item as CodeGenerator>::codegen: self = Item { id: ItemId(1), local_id: Cell { value: None }, next_child_local_id: Cell { value: 1 }, canonical_name_cache: RefCell { value: None }, comment: None, annotations: Annotations { opaque: false, hide: false, use_instead_of: None, disallow_copy: false, private_fields: None, accessor_kind: None, constify_enum_variant: false, derives: [] }, parent_id: ItemId(0), kind: Type(Type { name: Some("mystruct"), layout: Some(Layout { size: 4, align: 1, packed: false }), kind: Comp(CompInfo { kind: Struct, fields: AfterComputingBitfieldUnits([]), template_params: [], methods: [], constructors: [], destructor: None, base_members: [], inner_types: [], inner_vars: [], has_own_virtual_method: false, has_destructor: false, has_nonempty_base: false, has_non_type_template_params: false, packed_attr: false, found_unknown_attr: false, is_forward_declaration: false }), is_const: false }) }
[2019-11-20T23:44:05Z DEBUG bindgen::codegen] <Type as CodeGenerator>::codegen: item = Item { id: ItemId(1), local_id: Cell { value: None }, next_child_local_id: Cell { value: 1 }, canonical_name_cache: RefCell { value: None }, comment: None, annotations: Annotations { opaque: false, hide: false, use_instead_of: None, disallow_copy: false, private_fields: None, accessor_kind: None, constify_enum_variant: false, derives: [] }, parent_id: ItemId(0), kind: Type(Type { name: Some("mystruct"), layout: Some(Layout { size: 4, align: 1, packed: false }), kind: Comp(CompInfo { kind: Struct, fields: AfterComputingBitfieldUnits([]), template_params: [], methods: [], constructors: [], destructor: None, base_members: [], inner_types: [], inner_vars: [], has_own_virtual_method: false, has_destructor: false, has_nonempty_base: false, has_non_type_template_params: false, packed_attr: false, found_unknown_attr: false, is_forward_declaration: false }), is_const: false }) }
[2019-11-20T23:44:05Z DEBUG bindgen::codegen] <CompInfo as CodeGenerator>::codegen: item = Item { id: ItemId(1), local_id: Cell { value: None }, next_child_local_id: Cell { value: 1 }, canonical_name_cache: RefCell { value: None }, comment: None, annotations: Annotations { opaque: false, hide: false, use_instead_of: None, disallow_copy: false, private_fields: None, accessor_kind: None, constify_enum_variant: false, derives: [] }, parent_id: ItemId(0), kind: Type(Type { name: Some("mystruct"), layout: Some(Layout { size: 4, align: 1, packed: false }), kind: Comp(CompInfo { kind: Struct, fields: AfterComputingBitfieldUnits([]), template_params: [], methods: [], constructors: [], destructor: None, base_members: [], inner_types: [], inner_vars: [], has_own_virtual_method: false, has_destructor: false, has_nonempty_base: false, has_non_type_template_params: false, packed_attr: false, found_unknown_attr: false, is_forward_declaration: false }), is_const: false }) }
@emilio
Copy link
Contributor

emilio commented Nov 21, 2019

In C all structs need to have a different address. It is unexpected that the size is four in windows though...

@colindr
Copy link
Author

colindr commented Nov 21, 2019

I was expecting it to not have an _address field because that is what is generated on Linux. The "Expected Results" in the issue is the output that I get when I run bindgen on Linux with the same input.

@emilio
Copy link
Contributor

emilio commented Nov 25, 2019

Ah, I didn't notice that... That's weird indeed, probably MSVC has a different ABI than gcc for empty structs and we're choking on it.

@emilio emilio added the bug label Nov 25, 2019
@LunarLambda
Copy link

LunarLambda commented Jan 1, 2021

It is worth mentioning that the C standard makes empty structs UB.

(C11, 6.7.2.1 Structure and union specifiers p8) "If the struct-declaration-list does not contain any named members, either directly or via an anonymous structure or anonymous union, the behavior is undefined."

MSVC seems to reject this outright, GCC makes it size zero.
In C++, however, empty structs are valid and always 1 byte. (MSVC, GCC)

Not sure what clang says on Windows. Might mimick GCC's behaviour.
It'd probably be best to reject empty C structs altogether

@Dushistov
Copy link
Contributor

rustc also has problems with repr(C) and MSVC: rust-lang/rust#81996

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

No branches or pull requests

4 participants