long long alignment problem (MSVC vs. GCC) - c

I'm writing C cross-platform library but eventually I've got error in my unittests, but only on Windows machines. I've tracked the problem and found it's related to alignment of structures (I'm using arrays of structures to hold data for multiple similar objects). The problem is: memset(sizeof(struct)) and setting structures members one by one produce different byte-to-byte result and therefore memcmp() returns "not equal" result.
Here the code for illustration:
#include <stdio.h>
#include <string.h>
typedef struct {
long long a;
int b;
} S1;
typedef struct {
long a;
int b;
} S2;
S1 s1, s2;
int main()
{
printf("%d %d\n", sizeof(S1), sizeof(S2));
memset(&s1, 0xFF, sizeof(S1));
memset(&s2, 0x00, sizeof(S1));
s1.a = 0LL; s1.b = 0;
if (0 == memcmp(&s1, &s2, sizeof(S1)))
printf("Equal\n");
else
printf("Not equal\n");
return 0;
}
This code with MSVC 2003 # Windows produce following output:
16 8
Not equal
But the same code with GCC 3.3.6 # Linux works as expected:
12 8
Equal
This makes my unit-testing very hard.
Am I understand correctly that MSVC uses size of biggest native type (long long) to determine alignment to structure?
Can somebody give me advice how can I change my code to make it more robust against this strange alignment problem? In my real code I'm working with arrays of structures via generic pointers to execute memset/memcmp and I'm usually don't know exact type, I have only sizeof(struct) value.

Your unit test's expectation is wrong. It (or the code it tests) should not scan the structure's buffer byte-by-byte. For byte-precise data the code should create a byte buffer explicitly on stack or on heap and fill it with the extracts from each member. The extracts can be obtained in CPU-endianness-independent way by using the right shift operation against the integer values and casting the result by the byte type such as (unsigned char).
BTW, your snippet writes past s2. You could fix that by changing this
memset(&s2, 0x00, sizeof(S1));
s1.a = 0LL; s1.b = 0;
if (0 == memcmp(&s1, &s2, sizeof(S1)))
to this,
memset(&s2, 0x00, sizeof(S2));
s1.a = 0LL; s1.b = 0;
if (0 == memcmp(&s1, &s2, sizeof(S2)))
but the result is technically "undefined" because the alignment of members in the structures is compiler-specific.

GCC Manual:
Note that the alignment of any given struct or union type is required by the ISO C standard to be at least a perfect multiple of the lowest common multiple of the alignments of all of the members of the struct or union in question.
Also, this typically introduces an element of padding (i.e. filler bytes to have the structure aligned). You can use the #pragma with an argument of packed. Note, #pragmas are NOT a portable way of working. Unfortunately, this is also about the only way of working in your case.
References:
Here GCC on structure alignment.
MSDN structure alignment.

What we have done is used the #pragma pack to specify how big the objects should be:
#pragma pack(push, 2)
typedef struct {
long long a;
int b;
} S1;
typedef struct {
long a;
int b;
} S2;
#pragma pack(pop)
If you do this, the structures will be the same size on both platforms.

Note that this is not a 'strange' alignment problem. MSVC has chosen to ensure that the struct is aligned on a 64-bit boundary since it has a 64-bit member so it adds some padding at the end of the struct to ensure that arrays of those objects will have each element properly aligned. I'm actually surprised that GCC doesn't do the same.
I'm curious what you're unit testing does that hits a snag with this - most of the time alignment of structure members isn't necessary unless you need to match a binary file format or a wire protocol or you really need to reduce the memory used by a structure (especially used in embedded systems). Without knowing what you're trying to do in your tests I don't think a good suggestion can be given. Packing the structure might be a solution, but it comes at some cost - performance (especially on non-Intel platforms) and portability (how struct packing is set up is can be different from compiler to compiler). These may not matter to you, but there might be a better way to solve the problem in your case.

You can either do something like
#ifdef _MSC_VER
#pragma pack(push, 16)
#endif
/* your struct defs */
#ifdef _MSC_VER
#pragma pack(pop)
#endif
to give a compiler directive forcing alignment
Or go into the project options and change the default struct alignment [under Code Generation]

Structure padding for 64-bit values is different on different compilers. I've seen differences between even between gcc targets.
Note that explicitly padding to 64-bit alignment will only hide the problem. It will come back if you begin naively nesting structures, because the compilers will still disagree on the natural alignment of the inner structures.

Related

GCC is complaining about using multiple __attributes__

I've got some code provided by a vendor that I'm using and its typedef'ing an enum with __attribute__((aligned(1), packed)) and GCC is complaining about the multiple attributes:
error: ignoring attribute 'packed' because it conflicts with attribute 'aligned' [-Werror=attributes]
Not sure what the best approach is here. I feel like both of these attributes are not necessary. Would aligned(1) not also make it packed? And is this even necessary for an enum? Wouldn't it be best to have the struct that this enum goes into be packed?
Thanks!
I've removed the packed attribute and that works to make GCC happy but I want to make sure that it will still behave the same. This is going into an embedded system that relies on memory mapped registers so I need the mappings to be correct or else things won't work.
Here's an example from the code supplied by the vendor:
#define DMESCC_PACKED __attribute__ ((__packed__))
#define DMESCC_ENUM8 __attribute__ ((aligned (1), packed))
typedef enum DMESCC_ENUM8 {DMESCC_OFF, DMESCC_ON} dmescc_bittype_t;
typedef volatile struct {
dmescc_bittype_t rx_char_avail : 1;
dmescc_bittype_t zero_count : 1;
dmescc_bittype_t tx_buf_empty : 1;
dmescc_bittype_t dcd : 1;
dmescc_bittype_t sync_hunt : 1;
dmescc_bittype_t cts : 1;
dmescc_bittype_t txunderrun_eom : 1;
dmescc_bittype_t break_abort : 1;
} DMESCC_PACKED dmescc_rr0_t;
When I build the above code I get the GCC error I mentioned above.
Documentation here: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#Common-Variable-Attributes emphasis mine:
When used on a struct, or struct member, the aligned attribute can only increase the alignment; in order to decrease it, the packed attribute must be specified as well. When used as part of a typedef, the aligned attribute can both increase and decrease alignment, and specifying the packed attribute generates a warning.
Note that the effectiveness of aligned attributes for static variables may be limited by inherent limitations in the system linker and/or object file format. On some systems, the linker is only able to arrange for variables to be aligned up to a certain maximum alignment. (For some linkers, the maximum supported alignment may be very very small.) If your linker is only able to align variables up to a maximum of 8-byte alignment, then specifying aligned(16) in an __attribute__ still only provides you with 8-byte alignment. See your linker documentation for further information.
Older GNU documentation said something else. Also, I don't know what the documentation is trying to say here: "specifying the packed attribute generates a warning", because there is no warning in case I do this (gcc x86_64 12.2.0 -Wall -Wextra):
typedef struct
{
char ch;
int i;
} __attribute__((aligned(1), packed)) aligned_packed_t;
However, this effectively places the struct on a 5 byte offset, where the first address appears to be 8 byte aligned (which might be a thing of the linker as suggested in the above docs). We'd have to place it in an array to learn more.
Since I don't really don't trust the GNU documentation, I did some trial & error to reveal how these work in practice. I created 4 structs:
one with aligned(1)
one with such a struct as its member and also aligned(1) in itself
one with packed
one with both aligned(1) and packed (again this compiles cleanly no warnings)
For each struct I created an array, then printed the address of the first 2 array items. Example:
#include <stdio.h>
typedef struct
{
char ch;
int i;
} __attribute__((aligned(1))) aligned_t;
typedef struct
{
char ch;
aligned_t aligned_member;
} __attribute__((aligned(1))) struct_aligned_t;
typedef struct
{
char ch;
int i;
} __attribute__((packed)) packed_t;
typedef struct
{
char ch;
int i;
} __attribute__((aligned(1),packed)) aligned_packed_t;
#define TEST(type,arr) \
printf("%-16s Address: %p Size: %zu\n", #type, (void*)&arr[0], sizeof(type)); \
printf("%-16s Address: %p Size: %zu\n", #type, (void*)&arr[1], sizeof(type));
int main (void)
{
aligned_t arr1 [3];
struct_aligned_t arr2 [3];
packed_t arr3 [3];
aligned_packed_t arr4 [3];
TEST(aligned_t, arr1);
TEST(struct_aligned_t, arr2);
printf(" Address of member: %p\n", arr2[0].aligned_member);
TEST(packed_t, arr3);
TEST(aligned_packed_t, arr4);
}
Output on x86 Linux:
aligned_t Address: 0x7ffc6f3efb90 Size: 8
aligned_t Address: 0x7ffc6f3efb98 Size: 8
struct_aligned_t Address: 0x7ffc6f3efbb0 Size: 12
struct_aligned_t Address: 0x7ffc6f3efbbc Size: 12
Address of member: 0x40123000007fd8
packed_t Address: 0x7ffc6f3efb72 Size: 5
packed_t Address: 0x7ffc6f3efb77 Size: 5
aligned_packed_t Address: 0x7ffc6f3efb81 Size: 5
aligned_packed_t Address: 0x7ffc6f3efb86 Size: 5
The first struct with just aligned(1) didn't make any difference against a normal struct.
The second struct where the first struct was included as a member, to see if it would be misaligned internally, did not pack it any tighter either, nor did the member get allocated at a misaligned (1 byte) address.
The third struct with only packed did get allocated at a potentially misaligned address and packed into 5 bytes.
The fourth struct with both aligned(1) and packed works just as the one that had packed only.
So my conclusion is that "the aligned attribute can only increase the alignment" is correct and as expected aligned(1) is therefore nonsense. However, you can use it to increase the alignment. ((aligned(16), packed) did give 16 bit size, which effectively cancels packed.
Also I can't make sense of this part of the manual:
When used as part of a typedef, the aligned attribute can both increase and decrease alignment, and specifying the packed attribute generates a warning.
Either I'm missing something or the docs are wrong (again)...
Not sure what the best approach is here. I feel like both of these
attributes are not necessary. Would aligned(1) not also make it
packed?
No, it wouldn't. From the docs:
The aligned attribute specifies a minimum alignment (in bytes) for
variables of the specified type.
and
When attached to an enum definition, the packed attribute indicates that the smallest integral type should be used.
These properties are related but neither is redundant with the other (which makes GCC's diagnostic surprising).
And is this even necessary for an enum? Wouldn't it be best to
have the struct that this enum goes into be packed?
It is meaningful for an enum to be packed regardless of how it is used to compose other types. In particular, having packed on an enum is (only) about the storage size of objects of the enum type. It does not imply packing of structure types that have members of the enum type, but you might want that, too.
On the other hand, the alignment requirement of the enum type is irrelevant to the layout of structure types that have the packed attribute. That's pretty much the point of structure packing.
I've removed the packed attribute and that works to make GCC happy but
I want to make sure that it will still behave the same. This is going
into an embedded system that relies on memory mapped registers so I
need the mappings to be correct or else things won't work.
If only one of the two attributes can be retained, then packed should be that one. Removing it very likely does cause meaningful changes, especially if the enum is used as a structure member or as the type of a memory-mapped register. I can't guarantee that removing the aligned attribute won't also cause behavioral changes, but that's less likely.
It might be worth your while to ask the vendor what version of GCC they use for development and testing, and what range of versions they claim their code is compatible with.
Overall, however, the whole thing has bad code smell. Where it is essential to control storage size exactly, explicit-size integer types such as uint8_t should be used.
Addendum
With regard to the example code added to the question: that the enum type in question is used as the type of a bitfield changes the complexity of the question. Portable code steers well clear of bitfields.
The C language specification does not guarantee that an enum type such as that one can be used as the type of a bitfield member, so you're straight away into implementation-defined territory. Not that using one of the types the specification designates are supported would delay that very long, because many of the properties of bitfields and the structures containing them are implementation defined anyway, in particular,
which data types other than qualified and unqualified versions of _Bool, signed int, and unsigned int are allowed as the type of a bitfield member;
the size and alignment requirement of the addressible storage units in which bitfields are stored (the spec does not connect these in any way with bitfields' declared types);
whether bitfields assigned to the same addressible storage unit are arranged from least-significant position to most, or the opposite;
whether bitfields can be split across adjacent addressible storage units;
whether bitfield members may have atomic type.
GCC's definitions for these behaviors are here: https://gcc.gnu.org/onlinedocs/gcc/Structures-unions-enumerations-and-bit-fields-implementation.html#Structures-unions-enumerations-and-bit-fields-implementation. Note well that many of them depend on the target ABI.
To use the vendor code safely, you really need to know which compiler it was developed for and tested against, and if that's a version of GCC, what target ABI. If you learn or are willing to assume GCC targeting the same ABI that you are targeting, then keep packed, dump aligned(1), and test thoroughly. Otherwise, you'll probably want to do more research.

replacing "__attribute__ ((packed))" for compact structures by a standard (portable) C method

Conversion of several values to a byte-string for radio transmission has to avoid unneeded bytes. Using GCC on an ARM target (32 bit) I use "attribute ((packed))". This directive is GCC based (as I read somewhere here) and so not generally portable - which I would prefer. Example:
typedef struct __attribute__ ((packed)) {
uint8_t u8; // (*)
int16_t i16; // (*)
float v;
...
uint16_t cs; // (*)
}valset_t; // valset_t is more often used
valset_t vs;
(*) values would use 4 bytes without the ((packed)) attribute, instead of one or two as desired. Byte-wise access for transmission with:
union{
valset_t vs; // value-set
uint8_t b[sizeof(valset_t)]; // byte array
}vs_u;
using vs_u.b[i] .
Processing time is not critical here, as the transmission is much slower.
Endian is also not to be considered here, but a different C-compiler might be applied in some cases.
Elder posts to this task gave some insight, but maybe packing and alignment features were improved meanwhile in C ?c) .
Is there a more portable solution in C to perform this task?
Packing/padding isn't standardized, and therefore structs/unions are strictly speaking not portable. #pragma pack(1) is somewhat more common and supported by many different compilers (including gcc), but it is still not fully portable.
Also please note that padding exists for a reason, these structs with non-standard packing could be dangerous or needlessly inefficient on some systems.
The only 100% portable data type for storing protocols etc is an array of unsigned char. You can get only get fully portable structs if you write serializer/deserializer routines for them. This naturally comes at the expense of extra code. Example of deserialization:
valset_t data_to_valset (const unsigned char* data)
{
valset_t result;
result.something = ... ;
...
return result;
}
In case of a certain network endianess, you can convert from network endianess to CPU endianess inside the same routine.
Please note that you have to type it out like in the function example above. You cannot write code such as:
unsigned char data[n] = ... ;
valset_t* vs = (valset_t*)data; // BAD
This is bad in multiple different ways: alignment, padding, strict aliasing, endianess and so on.
It is possible to go the other way around though, using a unsigned char* to inspect or serialize a struct byte by byte. However, doing so doesn't solve the issues of padding bytes or endianess still.

How to create 24 bit unsigned integer in C

I am working on an embedded application where RAM is extremely tight.
For this purpose I need to create a 24 bit unsigned integer data type. I am doing this using a struct:
typedef struct
{
uint32_t v : 24;
} uint24_t;
However when I interrogate the size of a variable of this type, it returns "4", i.e.:
uint24_t x;
x.v = 0;
printf("Size = %u", sizeof(x));
Is there a way I can force this variable to have 3 bytes?
Initially I thought it was because it is forcing datatypes to be word aligned, but I can for example do this:
typedef struct
{
uint8_t blah[3];
} mytype;
And in that case the size comes out at 3.
Well, you could try to ensure that the structure only takes up the space you need, with something like:
#pragma pack(push, 1)
typedef struct { uint8_t byt[3]; } UInt24;
#pragma pack(pop)
You may have to provide those compiler directives (like the #pragma lines above) to ensure there's no padding but this will probably be the default for a structure with only eight-bit fields(a).
You would probably then have to pack/unpack real values to and from the structure, something like:
// Inline suggestion used to (hopefully) reduce overhead.
inline uint32_t unpack(UInt24 x) {
uint32_t retVal = x.byt[0];
retVal = retVal << 8 | x.byt[1];
retVal = retVal << 8 | x.byt[2];
return retVal;
}
inline UInt24 pack(uint32_t x) {
UInt24 retVal;
retVal.byt[0] = (x >> 16) & 0xff;
retVal.byt[1] = (x >> 8) & 0xff;
retVal.byt[2] = x & 0xff;
return retVal;
}
Note that this gives you big-endian values regardless of your actual architecture. This won't matter if you're exclusively packing and unpacking yourself, but it may be an issue if you want to use the memory blocks elsewhere in a specific layout (in which case you can just change the pack/unpack code to use the desired format).
This method adds a little code to your system (and a probably minimal performance penalty) so you'll have to decide if that's worth the saving in data space used.
(a) For example, both gcc 7.3 and clang 6.0 show 3 6 for the following program, showing that there is no padding either within or following the structure:
#include <stdio.h>
#include <stdint.h>
typedef struct { uint8_t byt[3]; } UInt24;
int main() {
UInt24 x, y[2];
printf("%zd %zd\n", sizeof(x), sizeof(y));
return 0;
}
However, that is just a sample so you may want to consider, in the interest of portable code, using something like #pragma pack(1), or putting in code to catch environments where this may not be the case.
A comment by João Baptista on this site says that you can use #pragma pack. Another option is to use __attribute__((packed)):
#ifndef __GNUC__
# define __attribute__(x)
#endif
struct uint24_t { unsigned long v:24; };
typedef struct uint24_t __attribute__((packed)) uint24_t;
This should work on GCC and Clang.
Note, however, that this will probably screw up alignment unless your processor supports unaligned access.
Initially I thought it was because it is forcing datatypes to be word aligned
Different datatypes can have different alignment. See for example the Objects and alignment doc.
You can use alignof to check, but it's totally normal for char or uint8_t to have 1-byte (ie, effectively no) alignment, but for uint32_t to have 4-bye alignment. I don't know if the alignment of bitfields is explicitly described, but inheriting it from the storage type seems reasonable enough.
NB. The reason for having alignment requirements is generally that it works better with the underlying hardware. If you do use #pragma pack or __attribute__((packed)) or whatever, you may take a performance hit as the compiler - or the memory hardware - silently handle misaligned accesses.
Just explicitly storing a 3-byte array is probably better, IMO.
To begin with, don't use bit-fields or structs. They may include padding as they please and bit-fields are non-portable in general.
Unless your CPU explicitly got 24 bit arithmetic instructions - which doesn't seem very likely unless it's some oddball DSP - then a custom data type will achieve nothing but extra stack bloat.
Most likely you will have to use uint32_t for all arithmetic. Meaning that your 24 bit type might not achieve much when it comes to saving RAM. If you invent some custom ADT with setter/getter (serialization/de-serialization) access, you are probably just wasting RAM since you get higher stack peak usage if the functions can't be inlined.
To actually save RAM you should rather revise your program design.
That being said, you can create a custom type based on an array:
typedef unsigned char u24_t[3];
Whenever you need to access the data, you memcpy it to/from a 32 bit type and then do all arithmetic on 32 bits:
u24_t u24;
uint32_t u32;
...
memcpy(&u32, u24, sizeof(u24));
...
memcpy(&u24, &u32, sizeof(u24));
But note that this assumes little endian, since we are only working with bits 0 to 2. In case of a big endian system, you will have to do memcpy((uint8_t*)&u32+1, ... to discard the MS byte.

Troubles while reading the struct size

If I debug the following code then I see the size value is 12 (as expected).
#include <cstdint>
int main(int argc, char *argv[])
{
typedef struct __attribute__((__packed__)) { int8_t value; } time;
typedef struct __attribute__((__packed__)) {
uint8_t msg[8];
// time t1;
uint32_t count;
} theStruct;
theStruct s;
int size = sizeof(s);
return 0;
}
Interestingly, removing the comment at "time t1;", the value of size goes to 16. I was expecting 13.
I know (more or less) that this is explained by the data structure padding story...
But, is there some way to avoid this issue?
What to do in order to read size = 13?
There are some issues with MinGW's emulation of MSVC struct packing.
The workaround is to pass -mno-ms-bitfields flag to the compiler; this will cause it to use its own layout algorithm rather than attempt to emulate MSVC.
See also Struct packing and alignment with mingw (ARM but may be the same issue).
It is clearly an alignement problem, meaning it has nothing to do with the language itself but all with the underlying platform.
If the platform knows (or thinks) that int32_t need an alignement of 4, it should add 3 bytes of padding after time.
Anyway __attribute__((__packed__)) is non standard C and will only be interpreted by gcc (*). Worse it leads to non portable programs : according to this answer on another question, it would cause a bus error on a Sparc architecture because of a misaligned int32_t.
I do know that x86 (and derivatives) architecture are now the most common, but other architecture may still exist ...
(*) according to Visual C++ equivalent of GCC's __attribute__ ((__packed__)), the MSVC equivalent is #pragma pack(push, 1)

Disable structure padding in C without using pragma

How can I disable structure padding in C without using pragma?
There is no standard way of doing this. The standard states that padding may be done at the discretion of the implementation. From C99 6.7.2.1 Structure and union specifiers, paragraph 12:
Each non-bit-field member of a structure or union object is aligned in an implementation-defined manner appropriate to its type.
Having said that, there's a couple of things you can try.
The first you've already discounted, using #pragma to try and convince the compiler not to pack. In any case, this is not portable. Nor are any other implementation-specific ways but you should check into them as it may be necessary to do it if you really need this capability.
The second is to order your fields in largest to smallest order such as all the long long types followed by the long ones, then all the int, short and finally char types. This will usually work since it's most often the larger types that have the more stringent alignment requirements. Again, not portable.
Thirdly, you can define your types as char arrays and cast the addresses to ensure there's no padding. But keep in mind that some architectures will slow down if the variables aren't aligned properly and still others will fail miserably (such as raising a BUS error and terminating your process, for example).
That last one bears some further explanation. Say you have a structure with the fields in the following order:
char C; // one byte
int I; // two bytes
long L; // four bytes
With padding, you may end up with the following bytes:
CxxxIIxxLLLL
where x is the padding.
However, if you define your structure as:
typedef struct { char c[7]; } myType;
myType n;
you get:
CCCCCCC
You can then do something like:
int *pInt = &(n.c[1]);
int *pLng = &(n.c[3]);
int myInt = *pInt;
int myLong = *pLng;
to give you:
CIILLLL
Again, unfortunately, not portable.
All these "solutions" rely on you having intimate knowledge of your compiler and the underlying data types.
Other than compiler options like pragma pack, you cannot, padding is in the C Standard.
You can always attempt to reduce padding by declaring the smallest types last in the structure as in:
struct _foo {
int a; /* No padding between a & b */
short b;
} foo;
struct _bar {
short b; /* 2 bytes of padding between a & b */
int a;
} bar;
Note for implementations which have 4 byte boundaries
On some architectures, the CPU itself will object if asked to work on misaligned data. To work around this, the compiler could generate multiple aligned read or write instructions, shift and split or merge the various bits. You could reasonably expect it to be 5 or 10 times slower than aligned data handling. But, the Standard doesn't require compilers to be prepared to do that... given the performance cost, it's just not in enough demand. The compilers that support explicit control over padding provide their own pragmas precisely because pragmas are reserved for non-Standard functionality.
If you must work with unpadded data, consider writing your own access routines. You might want to experimenting with types that require less alignment (e.g. use char/int8_t), but it's still possible that e.g. the size of structs will be rounded up to multiples of 4, which would frustrate packing structures tightly, in which case you'll need to implement your own access for the entire memory region.
Either you let compiler do padding, or tell it not to do using #pragma, either you just use some bunch of bytes like a char array, and you build all your data by yourself (shifting and adding bytes). This is really inefficient but you'll exactly control the layout of the bytes. I did that sometimes preparing network packets by hand, but in most case it's a bad idea, even if it's standard.
If you really want structs without padding: Define replacement datatypes for short, int, long, etc., using structs or classes that are composed only of 8 bit bytes. Then compose your higher level structs using the replacement datatypes.
C++'s operator overloading is very convenient, but you could achieve the same effect in C using structs instead of classes. The below cast and assignment implementations assume the CPU can handle misaligned 32bit integers, but other implementations could accommodate stricter CPUs.
Here is sample code:
#include <stdint.h>
#include <stdio.h>
class packable_int { public:
int8_t b[4];
operator int32_t () const { return *(int32_t*) b; }
void operator = ( int32_t n ) { *(int32_t*) b = n; }
};
struct SA {
int8_t c;
int32_t n;
} sa;
struct SB {
int8_t c;
packable_int n;
} sb;
int main () {
printf ( "sizeof sa %d\n", sizeof sa ); // sizeof sa 8
printf ( "sizeof sb %d\n", sizeof sb ); // sizeof sb 5
return 0;
}
We can disable structure padding in c program using any one of the following methods.
-> use __attribute__((packed)) behind definition of structure. for eg.
struct node {
char x;
short y;
int z;
} __attribute__((packed));
-> use -fpack-struct flag while compiling c code. for eg.
$ gcc -fpack-struct -o tmp tmp.c
Hope this helps.
Thanks.

Resources