This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What does 'unsigned temp:3' means
A struct's definition goes like this,
typedef struct
{
uint32_t length : 8;
uint32_t offset : 24;
uint32_t type : 8;
} A;
I haven't seen this kind of definition before, what does it mean by :8 and :24?
It's defining bitfields. This tells the compiler that length is 8 bits, offset is 24 bits and type is also 8 bits.
Refer the following link. They are bit-fields. http://www.cs.cf.ac.uk/Dave/C/node13.htmlhttp://en.wikipedia.org/wiki/Bit_field
#include <stdio.h>
typedef unsigned int uint32_t;
#pragma pack(push, 1)
typedef struct
{
uint32_t length : 8;
uint32_t offset : 24;
uint32_t type : 8;
} A;
typedef struct
{
uint32_t length;
uint32_t offset;
uint32_t type;
} B;
#pragma pack(pop)
int main()
{
printf("\n Size of Struct: A:%d B:%d", sizeof(A), sizeof(B));
return 0;
}
Structure A's size will be 5 Bytes where as B's size will be 12 bytes.
This notation defines bit fields, i.e. the size in number of bits for that structure variable.
Related
This question already has answers here:
Why isn't sizeof for a struct equal to the sum of sizeof of each member?
(13 answers)
Closed 1 year ago.
And I define a struct :
#include <stdint.h>
#include <stdio.h>
#define O(type, field) (size_t)(&(((type *)0)->field))
struct byname {
int16_t int16;
int32_t int32;
int64_t int64;};
Then I use sizeof(struct byname) and it return 16 which I can understand.
However when I define the like adding a int8_t:
#include <stdint.h>
#include <stdio.h>
#define O(type, field) (size_t)(&(((type *)0)->field))
struct byname {
int16_t int16;
int32_t int32;
int64_t int64;
int8_t int8;};
It just return 24, I think a int8 only takes 1 by and there are 3 bys padding according to data alignment, so I think the answer should be 20.
Anyone can kindly explain to me how the 24 comes?
The structure contains int64_t. If the compiler thinks that int64_t should be aligned to 8-byte boundary, it is reasonable to make the size of the structure multiple of 8 (therefore 24 bytes instead of 20) to align every int64_t int64; in an array of struct byname to 8-byte boundary.
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?
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;
};
This question already has answers here:
Why isn't sizeof for a struct equal to the sum of sizeof of each member?
(13 answers)
Closed 6 years ago.
I have the following code:
#include<stdio.h>
typedef struct _node_1
{
int number;
int scores;
int xyz;
double p;
} Node_1;
typedef struct _node_2
{
int number;
int scores;
int xyz;
struct _node_2 *p;
} Node_2;
typedef struct _node_3
{
int number;
int scores;
int xyz;
struct _node_2 p;
} Node_3;
int main()
{
printf("%d\n",sizeof(Node_1));
printf("%d\n",sizeof(Node_2));
printf("%d",sizeof(Node_3));
return 0;
}
and the output is:
24
24
40
My question is why the result of these 3 examples's outputs are like this and how do we exactly determine the size of a structure? BTW, my operating system is 64-bit. Thank you!
For the first & second one, you would expect 4+4+4+8 = 20 because of the size of the internal data, but you forgot about alignment.
64-bit pointers & doubles (64 bit) too need to be aligned to 8-byte boundary. The compiler inserts a 4-byte padding for this.
I am implementing a radio standard and have hit a problem with unions in structure and memory size. In the below example I need this structure to located in a single byte of memory (as per the radio standard) but its currently giving me a size of 2 bytes. After much digging I understand that its because the Union's "size" is byte rather than 3 bits...but havent worked out a way around this.
I have looked at:
Bitfields in C with struct containing union of structs; and
Will this bitfield work the way I expect?
But neither seem to give me a solution.
Any ideas?
Thanks!
#ifdef WIN32
#pragma pack(push)
#pragma pack(1)
#endif
typedef struct three_bit_struct
{
unsigned char bit_a : 1;
unsigned char bit_b : 1;
unsigned char bit_c : 1;
}three_bit_struct_T;
typedef union
{
three_bit_struct_T three_bit_struct;
unsigned char another_three_bits : 3;
}weird_union_T;
typedef struct
{
weird_union_T problem_union;
unsigned char another_bit : 1;
unsigned char reserved : 4;
}my_structure_T;
int _tmain(int argc, _TCHAR* argv[])
{
int size;
size = sizeof(my_structure_T);
return 0;
}
#ifdef WIN32
#pragma pack(pop)
#endif
The problem is that the size of three_bit_struct_T will be rounded up to the nearest byte* regardless of the fact that it only contains three bits in its bitfield. A struct simply cannot have a size which is part-of-a-byte. So when you augment it with the extra fields in my_structure_T, inevitably the size will spill over into a second byte.
To cram all that stuff into a single byte, you'll have to put all the bitfield members in the outer my_structure_T rather than having them as an inner struct/union.
I think the best you can do is have the whole thing as a union.
typedef struct
{
unsigned char bit_a : 1;
unsigned char bit_b : 1;
unsigned char bit_c : 1;
unsigned char another_bit : 1;
unsigned char reserved : 4;
} three_bit_struct_T;
typedef struct
{
unsigned char another_three_bits : 3;
unsigned char another_bit : 1;
unsigned char reserved : 4;
} another_three_bit_struct_T;
typedef union
{
three_bit_struct_T three_bit_struct;
another_three_bit_struct_T another_three_bit_struct;
} my_union_T;
(*) or word, depending on alignment/packing settings.
Two good advices: never use struct/union for data protocols, and never use bit-fields anywhere in any situation.
The best way to implement this is through bit masks and bit-wise operators.
#define BYTE_BIT7 0x80u
uint8_t byte;
byte |= BYTE_BIT_7; // set bit to 1
byte &= ~BYTE_BIT_7; // set bit to 0
if(byte & BYTE_BIT_7) // check bit value
This code is portable to every C compiler in the world and also to C++.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why isn't sizeof for a struct equal to the sum of sizeof of each member?
Extra bytes when declaring a member of a struct as uint32_t
For some reason, the sizeof operator returns a bogus size for this structure (48 instead of 40):
typedef struct mbdb_file_info {
uint16_t mode;
uint32_t unk0;
uint32_t unk1;
uint32_t user_id;
uint32_t group_id;
uint32_t time0;
uint32_t time1;
uint32_t time2;
uint64_t length;
uint8_t flag;
uint8_t property_count;
} mbdb_file_info;
So here is a simple test:
printf("%ld %ld %ld %ld: %ld", sizeof(uint8_t),
sizeof(uint16_t),
sizeof(uint32_t),
sizeof(uint64_t),
sizeof(mbdb_file_info));
Which prints:
1 2 4 8: 48
How does this happen? If you add all the sizes together you get 40, not 48. Where on earth does the 48 come from?
And if it's some weird x86-64 perk, how do I ensure that the all the fields of the structures occupy the amounts I want them to occupy (I'm casting a bunch of bytes to this structure)?
The compiler may append some bytes in the middle of the struct in order to align the struct members. The size of the struct is at least the sum of he members' size, but not limited to it.
You can also get rid of the padding by re-ordering your struct members. For example, if you declare the 64-bit, then 32's, then 16, then 8's, it will be naturally aligned and not have extra padding bytes.
Because of the structure padding (not sure which was the term here). The biggest field is 64bit, so everything's aligned according it. So, we have:
typedef struct mbdb_file_info {
uint16_t mode; // 16 +
uint32_t unk0; // 32 = 48, so add 16 more to align to 64bit;
uint32_t unk1; // this
uint32_t user_id; // and this give 64bits ;
uint32_t group_id; // again this
uint32_t time0; // plus this - 64bits;
uint32_t time1; // this
uint32_t time2; // and this = 64bit ;
uint64_t length; // this is 64 by itself
uint8_t flag; // this
uint8_t property_count; // +this is 16, add 48 for the alignment
} mbdb_file_info; // when you sum all bits (+ the additional for padding)
// you have exactly 48B
Alignment. Certain data types are aligned at certain boundaries (read: addresses divisible by a factor of 2, e.g. 16), dependent on the architecture, and this causes padding in the structure.
There are compiler options to suppress this behaviour, and the gcc documentation tells you how to use the aligned attribute for it.
This is called structure padding for alignment.
What is likely happening is that 8- and 16-bit values are padded to 32 bit and the whole structure is padded to be a multiple of machine word size (8).