0

Problem is solved. Mistake was not to rethink about given datatypes... The size of following structure is bigger than it should be:

typedef unsigned char    byte;
typedef unsigned short   word;
typedef unsigned long    dword;

struct Y
{
 short      h;
 byte       i;       
}
#if defined (__GNUC__)
    __attribute__((__packed__));
#endif

struct X
{
   short    a;
   byte     b;
   byte     c;
   word     d;
   dword    e;
   byte     f;
   byte     g;
   word     h;
   short    i;
   struct Y G[8];
}
#if defined (__GNUC__)
    __attribute__((__packed__));
#endif

printf("size of X should be 40 but is %i", sizeof(struct X));

Output:

size of X should be 40 but is 44

I need this structure with a size of 40 Bytes (sum of all elements), 44 is the lowest I can reach. Compiler is GCC C, byte is unsigned char, word is unsigned short and dword is unsigned long. sizeof(Y) is 3. What is the problem here?

Mirhan
  • 3
  • 2
  • 1
    What are `byte`, `word` and `dword`? Those are not standard types. Also, you are printing "size of X should be", but you output the size of `Y` instead. Finally, what is `struct J`? Please, ensure your code is a **[mre]**. – Marco Bonelli Mar 03 '21 at 14:19
  • byte is unsigned char, word is unsigned short and dword is unsigned long – Mirhan Mar 03 '21 at 14:20
  • Well, add that to the code in the question then! Also, we still don't know what `struct J` is. Did you mean `struct Y`? I also really doubt `sizeof(Y)` is 44. – Marco Bonelli Mar 03 '21 at 14:22
  • 3
    Instead of implementation dependant types like `short` etc I suggest to use types from `stdint.h`, e.g. `int16_t` etc. You can use `offsetof` and `sizeof` for individual structure fields to check what's different from your expectations. – Bodo Mar 03 '21 at 14:28
  • What is `sizeof(dword)` (or `sizeof(unsigned long)`) on this system? If it is 8 rather than the 4 you expect, then that would account for the difference between 40 and 44 bytes. – Ian Abbott Mar 03 '21 at 14:30
  • i did not write this struct but i have to work with it without changing it. Without the dword variable in X i get the right size – Mirhan Mar 03 '21 at 14:35
  • Why not inspect the `sizeof`s and `offsetof`s of the individual members? At the moment, most of the energy in trying to answer is wasted by guessing the types and their sizes. – M Oehm Mar 03 '21 at 14:40
  • This is also relevant: [**Is gcc's __attribute__((packed)) / #pragma pack unsafe?**](https://stackoverflow.com/questions/8568432/is-gccs-attribute-packed-pragma-pack-unsafe) The answer is "Yes". There are even examples of misaligned access failure on x84 systems: https://stackoverflow.com/questions/46790550/c-undefined-behavior-strict-aliasing-rule-or-incorrect-alignment and https://stackoverflow.com/questions/47510783/why-does-unaligned-access-to-mmaped-memory-sometimes-segfault-on-amd64 – Andrew Henle Mar 03 '21 at 14:59

1 Answers1

2

The types you define are flawed. Ideally I'd suppose that dword should be double the size of word, but you are defining the two as:

typedef unsigned short   word;  
typedef unsigned long    dword; 

And it turns out that on your platform sizeof(unsigned short) is 2, while sizeof(unsigned long) is 8, not 4.

You should really avoid such definitions and use the standard types provided in stdint.h:

byte  -> uint8_t
short -> uint16_t
word  -> uint16_t
dword -> uint32_t

Finally, your structure declaration is invalid if the macro __GNUC__ is not defined, because you would be missing the final semicolon (;). You can change it to something like this:

#if defined (__GNUC__)
__attribute__((__packed__))
#endif
struct Y
{
 uint16_t h;
 uint8_t  i;       
};
Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128