www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - How to fix the mismatch struct size

reply test123 <test123 gmail.com> writes:
```c
typedef struct {
   const char *str;
   size_t      len : 30;
   bool        initial : 1;
   bool        final : 1;
} VTermStringFragment;

struct VTerm
{
   const VTermAllocatorFunctions *allocator;
   void *allocdata;

   int rows;
   int cols;

   struct {
     unsigned int utf8:1;
     unsigned int ctrl8bit:1;
   } mode;

   struct {
     enum VTermParserState {
       NORMAL,
       CSI_LEADER,
       CSI_ARGS,
       CSI_INTERMED,
       DCS_COMMAND,
       /* below here are the "string states" */
       OSC_COMMAND,
       OSC,
       DCS,
       APC,
       PM,
       SOS,
     } state;

     bool in_esc : 1;

     int intermedlen;
     char intermed[INTERMED_MAX];

     union {
       struct {
         int leaderlen;
         char leader[CSI_LEADER_MAX];

         int argi;
         long args[CSI_ARGS_MAX];
       } csi;
       struct {
         int command;
       } osc;
       struct {
         int commandlen;
         char command[CSI_LEADER_MAX];
       } dcs;
     } v;

     const VTermParserCallbacks *callbacks;
     void *cbdata;

     bool string_initial;
   } parser;

}
```

VTermStringFragment for mingw-x64 clang size is 24, for unix-64 
is 16.

VTerm for mingw-x64 clang size is 144, fox unix-64 is 208.

VTerm for mingw-x86 clang size is 128.

and offsetoff also diff from unix.


how to translate this into D struct ?


Is this problem cause by clang has wrong layout?
May 15 2022
next sibling parent reply test123 <test123 gmail.com> writes:
On Monday, 16 May 2022 at 05:57:33 UTC, test123 wrote:
 Is this problem cause by clang has wrong layout?
and VTermStringFragment for mingw-x86 size is 12.
May 15 2022
parent test123 <test123 gmail.com> writes:
On Monday, 16 May 2022 at 05:58:17 UTC, test123 wrote:
 On Monday, 16 May 2022 at 05:57:33 UTC, test123 wrote:
 Is this problem cause by clang has wrong layout?
and VTermStringFragment for mingw-x86 size is 12.
VTerm->parser for mingw-x64 clang size is 144, fox unix-64 is 208. VTerm->parser for mingw-x86 clang size is 128.
May 15 2022
prev sibling parent reply Arjan <arjan ask.me.to> writes:
On Monday, 16 May 2022 at 05:57:33 UTC, test123 wrote:
 ```c
 typedef struct {
   const char *str;
   size_t      len : 30;
   bool        initial : 1;
   bool        final : 1;
 } VTermStringFragment;

 [...]
Without fully scrutinizing your code I suspect the issues you see are caused by: - alignment - struct context pointer see: https://dlang.org/spec/attribute.html#align and https://dlang.org/spec/attribute.html#static
May 16 2022
parent reply test123 <test123 gmail.com> writes:
On Monday, 16 May 2022 at 07:29:39 UTC, Arjan wrote:
 On Monday, 16 May 2022 at 05:57:33 UTC, test123 wrote:
 Without fully scrutinizing your code I suspect the issues you 
 see are caused by:
 - alignment
I know it is cause by alignment. my problem how to deal with diff alignment with diff platform. special when there is multi level nested struct.
 - struct context pointer
There is no struct context pointer since I translate all nested struct and union into static. struct work for linux with clang, but not for windows.
May 16 2022
parent reply Arjan <arjan ask.me.to> writes:
On Monday, 16 May 2022 at 12:51:01 UTC, test123 wrote:
 On Monday, 16 May 2022 at 07:29:39 UTC, Arjan wrote:
 On Monday, 16 May 2022 at 05:57:33 UTC, test123 wrote:
 Without fully scrutinizing your code I suspect the issues you 
 see are caused by:
 - alignment
I know it is cause by alignment. my problem how to deal with diff alignment with diff platform. special when there is multi level nested struct.
Nesting does not make a difference in c/c++, it does however in D.
 - struct context pointer
There is no struct context pointer since I translate all nested struct and union into static.
That is not shown in the code.
 struct work for linux with clang, but not for windows.
Its it not clear what you want to achieve, assuming you want these structs to be equal (binary compatible layout on systems with same endianness) - enforce in C/C++ the alignment to byte/word/dword/qword alignment. This could be done with compiler `#pragma pack` or from C++/11 `alignas` or c/11 `_Alignas` (see https://en.cppreference.com/w/cpp/language/alignas) to make sure the padding is the same. - **do not** use bitfields since the packing of adjacent fields is implementation (compiler) dependent. (most probably the cause for diff in size 16 <==> 24 as you observed) see https://en.cppreference.com/w/cpp/language/bit_field - make sure the type's used in the struct are architecture independent, size of int in c/c++ is dependent on target arch x86=> 32bits x86_64 64bits. Its fixed in D. - make sure the size_t is the same type and size for all platforms - use static struct in D - use the correct corresponding types https://dlang.org/spec/type.html in D or use core.stdc.stdint type aliases
May 16 2022
parent reply test123 <test123 gmail.com> writes:
On Monday, 16 May 2022 at 15:28:42 UTC, Arjan wrote:
 - enforce in C/C++ the alignment to byte/word/dword/qword 
 alignment. This could be done with compiler `#pragma pack` or 
 from C++/11 `alignas` or c/11 `_Alignas` (see 
 https://en.cppreference.com/w/cpp/language/alignas)
 to make sure the padding is the same.
 - **do not** use bitfields since the packing of adjacent fields 
 is implementation (compiler) dependent. (most probably the 
 cause for diff in size 16 <==> 24 as you observed) see 
 https://en.cppreference.com/w/cpp/language/bit_field
 - make sure the type's used in the struct are architecture 
 independent, size of int in c/c++ is dependent on target arch 
 x86=> 32bits x86_64 64bits. Its fixed in D.
 - make sure the size_t is the same type and size for all 
 platforms
 - use static struct in D
 - use the correct corresponding types 
 https://dlang.org/spec/type.html in D or use core.stdc.stdint 
 type aliases
I can not change c struct since I don't own the project but need deal with it. All subtype size is matched that is why posix test work (and also check offsetof is matched). The problem is even all subtype size is same, but not all platform has same memory layout.
May 17 2022
next sibling parent Tejas <notrealemail gmail.com> writes:
On Tuesday, 17 May 2022 at 09:40:40 UTC, test123 wrote:
 On Monday, 16 May 2022 at 15:28:42 UTC, Arjan wrote:
 [...]
I can not change c struct since I don't own the project but need deal with it. All subtype size is matched that is why posix test work (and also check offsetof is matched). The problem is even all subtype size is same, but not all platform has same memory layout.
Maybe `extern(Windows)` can do something? Also, maybe useful : https://forum.dlang.org/post/ktntbwppqgbbajpbmrcf forum.dlang.org
May 17 2022
prev sibling parent reply Arjan <arjan ask.me.to> writes:
On Tuesday, 17 May 2022 at 09:40:40 UTC, test123 wrote:
 On Monday, 16 May 2022 at 15:28:42 UTC, Arjan wrote:
 - enforce in C/C++ the alignment to byte/word/dword/qword 
 alignment. This could be done with compiler `#pragma pack` or 
 from C++/11 `alignas` or c/11 `_Alignas` (see 
 https://en.cppreference.com/w/cpp/language/alignas)
 to make sure the padding is the same.
 - **do not** use bitfields since the packing of adjacent 
 fields is implementation (compiler) dependent. (most probably 
 the cause for diff in size 16 <==> 24 as you observed) see 
 https://en.cppreference.com/w/cpp/language/bit_field
 - make sure the type's used in the struct are architecture 
 independent, size of int in c/c++ is dependent on target arch 
 x86=> 32bits x86_64 64bits. Its fixed in D.
 - make sure the size_t is the same type and size for all 
 platforms
 - use static struct in D
 - use the correct corresponding types 
 https://dlang.org/spec/type.html in D or use core.stdc.stdint 
 type aliases
I can not change c struct since I don't own the project but need deal with it.
Do you know how this 'c' part is build? Which compiler and compiler flags? Than you should be able to 'deduce' the alignment used an possibly the packing of bitfields. When you know these things you are able to craft the D equivalent. Another option is just to figure out the layout at runtime using a on purpose filled struct from 'c' with 'marker patterns' in the struct fields.
May 17 2022
parent reply test123 <test123 gmail.com> writes:
On Tuesday, 17 May 2022 at 10:05:21 UTC, Tejas wrote:
 Maybe `extern(Windows)` can do something?
 Also, maybe useful : 
 https://forum.dlang.org/post/ktntbwppqgbbajpbmrcf forum.dlang.org
It is extern(C). On Tuesday, 17 May 2022 at 19:52:23 UTC, Arjan wrote:
 Do you know how this 'c' part is build? Which compiler and 
 compiler flags?
Clang with makefile.
 Than you should be able to 'deduce' the alignment used an 
 possibly the packing of bitfields.
no alignment is settings from C source file.
 Another option is just to figure out the layout at runtime 
 using a on purpose filled struct from 'c' with 'marker 
 patterns' in the struct fields.
sound like a solution, but not how to do this.
May 17 2022
parent Arjan <arjan ask.me.to> writes:
On Wednesday, 18 May 2022 at 04:08:57 UTC, test123 wrote:
 On Tuesday, 17 May 2022 at 10:05:21 UTC, Tejas wrote:
 Maybe `extern(Windows)` can do something?
 Also, maybe useful : 
 https://forum.dlang.org/post/ktntbwppqgbbajpbmrcf forum.dlang.org
It is extern(C). On Tuesday, 17 May 2022 at 19:52:23 UTC, Arjan wrote:
 Do you know how this 'c' part is build? Which compiler and 
 compiler flags?
Clang with makefile.
As can be observed from your first post, clang x64 does not pack all the bitields in the `VTermStringFragment` since the size is 24 bytes. alignment seems to be on address size (64bits 8bytes) Check the size of the other struct with bitfields `Vterm.mode` in the c program and the position of the bitfields if packed. With that information you should be able to create a matching layout in D.
 Than you should be able to 'deduce' the alignment used an 
 possibly the packing of bitfields.
no alignment is settings from C source file.
 Another option is just to figure out the layout at runtime 
 using a on purpose filled struct from 'c' with 'marker 
 patterns' in the struct fields.
sound like a solution, but not how to do this.
May 17 2022