@@ -62,6 +62,8 @@ $(H2 $(LNAME2 struct_layout, Struct Layout))
62
62
the first field and the start of the object.
63
63
)
64
64
65
+ $(P Structs with no fields of non-zero size (aka $(I Empty Structs)) have a size of one byte.)
66
+
65
67
$(P Non-static $(RELATIVE_LINK2 nested, function-nested D structs), which access the context of
66
68
their enclosing scope, have an extra field.
67
69
)
@@ -70,11 +72,21 @@ $(H2 $(LNAME2 struct_layout, Struct Layout))
70
72
$(OL
71
73
$(LI The default layout of the fields of a struct is an exact
72
74
match with the $(I associated C compiler).)
75
+ $(LI g++ and clang++ differ in how empty structs are handled. Both return `1` from `sizeof`,
76
+ however, clang++ does not push them onto the parameter stack while g++ does. This is a
77
+ binary incompatibility between g++ and clang++.
78
+ dmd follows clang++ behavior for OSX and FreeBSD, and g++ behavior for Linux and other
79
+ Posix platforms.
80
+ )
81
+ $(LI clang and gcc both return `0` from `sizeof` for empty structs. Using `extern "C++"`
82
+ in clang++ and g++ does not cause them to conform to the behavior of their respective C compilers.)
73
83
))
74
84
75
85
$(UNDEFINED_BEHAVIOR
76
86
$(OL
77
87
$(LI The padding data can be accessed, but its contents are undefined.)
88
+ $(LI Do not pass or return structs with no fields of non-zero size to `extern (C)` functions.
89
+ According to C11 6.7.2.1p8 this is undefined behavior.)
78
90
))
79
91
80
92
$(BEST_PRACTICE
@@ -83,6 +95,8 @@ $(H2 $(LNAME2 struct_layout, Struct Layout))
83
95
attributes to describe an exact match. Using a $(DDSUBLINK spec/version, static-assert, Static Assert)
84
96
to ensure the result is as expected.)
85
97
$(LI Although the contents of the padding are often zero, do not rely on that.)
98
+ $(LI Avoid using empty structs when interfacing with C and C++ code.)
99
+ $(LI Avoid using empty structs as parameters or arguments to variadic functions.)
86
100
))
87
101
88
102
$(H2 $(LNAME2 POD, Plain Old Data))
0 commit comments