__DECLARE_FLEX_ARRAY(T, member) macro expands to struct { struct {} __empty_member; T member[]; }; which is subtly wrong in C++ because sizeof(struct{}) is 1 not 0, changing UAPI structures layouts. This can be fixed by expanding to T member[]; Now g++ doesn't like "T member[]" either, throwing errors on the following code: struct S { union { T1 member1[]; T2 member2[]; }; }; or struct S { T member[]; }; Use "T member[0];" which seems to work and does the right thing wrt structure layout.
Showing the changes to include/uapi/linux (1 of 1 file). Show all
Unified · Split
| @@ -29,6 +29,11 @@ · 28 unmodified lines | |||
| 29 | struct TAG { MEMBERS } ATTRS NAME; \ | 29 | struct TAG { MEMBERS } ATTRS NAME; \ |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | #ifdef __cplusplus | ||
| 33 | /* sizeof(struct{}) is 1 in C++, not 0, can't use C version of the macro. */ | ||
| 34 | #define __DECLARE_FLEX_ARRAY(T, member) \ | ||
| 35 | T member[0] | ||
| 36 | #else | ||
| 32 | /** | 37 | /** |
| 33 | * __DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union | 38 | * __DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union |
| 34 | * | 39 | * |
| @@ -44,6 +49,7 @@ · 9 unmodified lines | |||
| 44 | struct { } __empty_ ## NAME; \ | 49 | struct { } __empty_ ## NAME; \ |
| 45 | TYPE NAME[]; \ | 50 | TYPE NAME[]; \ |
| 46 | } | 51 | } |
| 52 | #endif | ||
| 47 | 53 | ||
| 48 | #ifndef __counted_by | 54 | #ifndef __counted_by |
| 49 | #define __counted_by(m) | 55 | #define __counted_by(m) |