How to do proper alignment in structs?

Each property in an SDNA struct needs to be manually aligned based on its size. Alignment is based on sizes used by a 64bit system (8 byte pointers) which then also aligns to sizes of a 32 bit system.

This mostly relates to allowing each struct to be written to and read back from disk as one chunk, while maintaining cross platform compatibility on all supported plaforms. Note that while compilers have options to align struct members to suit the processor, blender insists on manual alignment so that the alignment always matches on every platform.

Iā€™m sure there is (was?) a better explanation somewhere, but the following two wiki archive pages cover this issue.

https://archive.blender.org/wiki/index.php/Dev:Source/Architecture/SDNA_Notes/

https://archive.blender.org/wiki/index.php/Dev:Source/Data_Structures/DNAStructs/

@LazyDodo

I need help understanding this. I thought I had it figured out, until I changed a couple settings and hour later with tons of changes still get errors.

This works and I thought I knew why until I started changing things.

struct Object *object;
struct Collection *collection;

char operation;
char collection_operation;  
char solver;
char bm_flag;
char flags;  
char operand_display;  
short operand_type;     # Assuming up to this point it adds up to 8?

  
float double_threshold;     # Only 4 so we need to add 4?
char _pad1[4]; 

Doesnā€™t work

struct Object *object;
struct Collection *collection;

char operation;
char collection_operation;  
char solver;
char bm_flag; 
short operand_display;  
short operand_type;     # Should add up to 8?

  
float double_threshold;     # Only 4 so we need to add 4?
char _pad1[4]; 

still doesnā€™t work

struct Object *object;
struct Collection *collection;

char operation;
char collection_operation;  
char solver;
char bm_flag;
char _pad0[4];      # Only 4 so we need to add 4?
 
short operand_display;  
short operand_type;
char _pad1[4];     # Only 4 so we need to add 4?
  
float double_threshold;     # Only 4 so we need to add 4?
char _pad2[4]; 

this still doesnā€™t work

struct Object *object;
struct Collection *collection;

char operation;
char collection_operation;  
char solver;
char bm_flag;
char _pad0[4];      # Only 4 so we need to add 4?
 
short operand_display;  
short operand_type;  
float double_threshold;     # Should add up to 8?

Edit:
This works ,but donā€™t understand why. Is it because I put float at top, then short and then char?

struct Object *object;
struct Collection *collection;

float double_threshold;
short operand_display;  
short operand_type; 

char operation;
char collection_operation;  
char solver;
char bm_flag;

char _pad0[4];

Best to look at the build output, makesdna will tell you what it wants you to do.

makesdna isnā€™t communicating very well. Had char _pad0[1] said to add 1 byte and I had to go to all the way to char _pad0[7] before there was no error? That makes no sense.

Without a repro or something to look at thereā€™s not much to do about this beyond going 'hehā€¦ weird"

Hereā€™s a couple examples.

#1

  struct Object *object;

  struct Collection *collection;

  float double_threshold;   

  char operation;  

  char solver;

  char flag;

  char od_flag;    

  char bm_flag;

gives

Sizeerror 8 in struct: BooleanModifierData (add 1 bytes)
Sizeerror 4 in struct: BooleanModifierData (add 1 bytes)

#2

  struct Object *object;
  struct Collection *collection;

  float double_threshold;   

  char operation;  
  char solver;
  char flag;
  char od_flag;    
  char bm_flag;
       
  char _pad0[1];

or

  struct Object *object;
  struct Collection *collection;

  float double_threshold;   

  char operation;  
  char solver;
  char flag;
  char od_flag;    
  char bm_flag;
       
  char _pad0;

now wants more?

Sizeerror 8 in struct: BooleanModifierData (add 2 bytes)
Sizeerror 4 in struct: BooleanModifierData (add 2 bytes)

It does seem to me that those error messages arenā€™t very helpful, as you say. You need to pad out to 8 byte boundaries. You are there with the first 4 chars after the float. Then the next char forces a need for 7 more to get you back to an 8 byte boundary.
In this particular case, maybe thereā€™s a way of combining the bits in flag and od_flag and thereby eliminate the need for any padding?

youā€™re not making it very easy to help you by stripping away all the context of what youā€™re doing.

hereā€™s the structure that i have in master

typedef struct BooleanModifierData {
  ModifierData modifier;

  struct Object *object;
  char operation;
  char solver;
  char flag;
  char bm_flag;
  float double_threshold;
} BooleanModifierData;

Youā€™re not supposed to re-order the fields, since it will as you have noticed give you alignment issues also ModifierData modifier; seems to be missing?

What is it that you are trying to accomplish?