What's the value of CMSG_ALIGN macro - c

Is it right to say the value of CMSG_ALIGN(i) is the minimum value of multiple of 8 and >=i if i is an unsigned int variable?
#include <stdio.h>
int main(void)
{
int i;
for (i=0; i<50; ++i) {
printf("%d\n", CMSG_ALIGN(i));
}
}
Output I get:
/* i CMSG_ALIGN(i)
*
* 0 0
* [1,8] 8
* [9,16] 16
*/

Is it right to say the value of CMSG_ALIGN(i) is the minimum value of
multiple of 8 and >=i if i is an unsigned int variable?
No. The alignment for a given value is not necessarily 8 on all platforms. If it were to be 8 always, CMSG_ALIGN() wouldn't be necessary at all.
You are probably on a 64-bit system. So it's aligned on 8 byte boundary. But if you run the same code on a 32-bit platform, you would probably see that it's a 4 byte alignment.
Note that CMCG_ALIGN() returns size_t. So %zu is the correct format string to print a size_t value.

Related

C structure with bits printing in hexadecimal

I have defined a structure as below
struct {
UCHAR DSatasetMGMT : 1;
UCHAR AtriburDeallocate : 1;
UCHAR Reserved6 : 6;
UCHAR Reserved7 : 7;
UCHAR DSatasetMGMTComply : 1;
}DatasetMGMTCMDSupport;
It is a 2 byte structure represented in bits. How should I print the whole 2 bytes of structure in hexadecimal. I tried
"DatasetMGMTCMDSupport : 0x%04X\n"
And
0x%04I64X\n
But not getting expected result.
I am getting 0x3DC18003 with 0x%04X\n while the correct data is 0x8003 "
I am using 64 bit windows system.
I need to know how to print 2 byte structure in hexadecimal.
Try using 0x%04hx\n. This tells printf to print out only the two bytes. You can read more about it here: https://en.wikipedia.org/wiki/Printf_format_string#Length_field
In contrast, the I64 in 0x%04I64X\n tells printf to print out a 64 bit integer, which is 8 bytes, and 0x%04X\n tells it to print out a default-size integer, which might be 4 bytes on your system.
The width 04 specifies a minimum width. Since the value needs more digits, they are printed.
From a C Standard point of view, you cannot rely on a particular layout of bit fields. Hence, any solution will at best have implementation-defined behaviour.
That being said, your expected output can be obtained. The structure fits in 2 bytes and if you print sizeof(DatasetMGMTCMDSupport) it should give the result 2.
The byte representation of DatasetMGMTCMDSupport can be printed and that is what you were attempting, but since your system has integer size 4, two additional bytes are included. To fix this, the following can be done:
#include <stdint.h>
#include <string.h>
#include <stdio.h>
...
uint16_t a;
memcpy(&a, &DatasetMGMTCMDSupport, sizeof(a));
printf("0x%04X", (unsigned)a);
This copies the 2 bytes of DatasetMGMTCMDSupport into a 2-byte integer variable and prints the hexadecimal representation of those 2 bytes only. If you are on a little-endian system, you should see 0x8003.
A more general approach would be to directly print the bytes of DatasetMGMTCMDSupport:
for(unsigned i = 0; i < sizeof(DatasetMGMTCMDSupport); i++)
{
printf("%02X", (unsigned)((unsigned char *)&DatasetMGMTCMDSupport)[i]);
}
This will most likely print 0380 (notice the byte order: first byte printed first).
To reverse the byte order is straightforward:
for(unsigned i = 0; i < sizeof(DatasetMGMTCMDSupport); i++)
{
printf("%02X", (unsigned)((unsigned char *)&DatasetMGMTCMDSupport)[sizeof(DatasetMGMTCMDSupport)-1-i]);
}
which should give 8003.

why itoa fuction returns 32 bits if the size of variable in 16 bit

size of short int is 2 bytes(16 bits) on my 64 bit processor and mingw compiler but when I convert short int variable to a binary string using itoa function
it returns string of 32 bits
#include<stdio.h>
int main(){
char buffer [50];
short int a=-2;
itoa(a,buffer,2); //converting a to binnary
printf("%s %d",buffer,sizeof(a));
}
Output
11111111111111111111111111111110 2
The answer is in understanding C's promotion of short datatypes (and char's, too!) to int's when those values are used as parameters passed to a function and understanding the consequences of sign extension.
This may be more understandable with a very simple example:
#include <stdio.h>
int main() {
printf( "%08X %08X\n", (unsigned)(-2), (unsigned short)(-2));
// Both are cast to 'unsigned' to avoid UB
return 0;
}
/* Prints:
FFFFFFFE 0000FFFE
*/
Both parameters to printf() were, as usual, promoted to 32 bit int's. The left hand value is -2 (decimal) in 32bit notation. By using the cast to specify the other parameter should not be subjected to sign extension, the printed value shows that it was treated as a 32 bit representation of the original 16 bit short.
itoa() is not available in my compiler for testing, but this should give the expected results
itoa( (unsigned short)a, buffer, 2 );
your problem is so simple , refer to itoa() manual , you will notice its prototype which is
char * itoa(int n, char * buffer, int radix);
so it takes an int that to be converted and you are passing a short int so it's converted from 2 byte width to 4 byte width , that's why it's printing a 32 bits.
to solve this problem :
you can simply shift left the array by 16 position by the following simple for loop :
for (int i = 0; i < 17; ++i) {
buffer[i] = buffer[i+16];
}
and it shall give the same result , here is edited version of your code:
#include<stdio.h>
#include <stdlib.h>
int main(){
char buffer [50];
short int a= -2;
itoa(a,buffer,2);
for (int i = 0; i < 17; ++i) {
buffer[i] = buffer[i+16];
}
printf("%s %d",buffer,sizeof(a));
}
and this is the output:
1111111111111110 2

how to find how many bits exist in a int number and storing each bit in an int array

I have something like int i=10 it could be i=1000 or i=10400233
I like to store each bit from any number stored in int i=10//,etc. in an array. Is it possible in C
I just don't get it how can we find the relationship between bits and int variable with a number stored in it
example inputs
int i=10; // I want int array[]={1,0,1,0};
int i=15; // I want int array[] ={1,1,1,1};
int i=21 // I want int array[] ={1,0,1,0,1};
I just don't get it how can we find the relationship between bits and int variable with a number stored in it
First it's important to understand that the number of bits used to store an int is a fixed number on the specific system being used. Different systems may use a different number of bits.
BUT ... The number of bits doesn't depend on the value held by the int. The number of bits used to store an int is a system-specific constant.
You can fid the number of bits like:
printf("int is %zu chars and each char is %d bits so in total %zu bits\n",
sizeof(int), // Chars per int
CHAR_BIT, // Bits per char
sizeof(int) * CHAR_BIT); // Bits per int
On my system I get:
int is 4 chars and each char is 8 bits so in total 32 bits
Once you have calculated the number of bits, you can create an array of that size. Either a VLA (variable length array) or a dynamic allocated array (i.e. using malloc).
This is how its done when sizeof(int) is 4 on my system
#define CHAR_BIT_C 8
int main()
{
int i=21;
int t[32];
for(int x=CHAR_BIT_C*sizeof(int)-1;x>=0;x--)
{
*(t+x)=i>>x&0b1;
}
for(int x=CHAR_BIT_C*sizeof(int)-1;x>=0;x--){
printf("%d ",*(t+x));
}
return 0;
}

value of members of unions with bit-fields

I'm trying to learn how memory is allocated for unions containing bit-fields.
I've looked at posts and questions similar to this and have understood that padding is involved most of the times depending on the order in which members are declared in structure.
1.
union Example
{ int i:2;
int j:9;
};
int main(void)
{
union Example ex;
ex.j=15;
printf("%d",ex.i);
}
Output: -1
2.
union Example
{ unsigned int i:2;
int j:9;
};
int main(void)
{
union Example ex;
ex.j=15;
printf("%d",ex.i);
}
Output: 3
Can someone please explain the output? Is it just the standard output for such cases?
I use the built-in gcc compiler in ubuntu
The way your compiler allocates bits for bit-fields in a union happens to overlap the low bits of j with the bits of i. Thus, when j is set to 15, the two bits of i are each set to 1.
When i is a two-bit signed integer, declared with int i:2, your compiler interprets it as a two-bit two’s complement number. With this interpretation, the bits 11 represent −1.
When i is a two-bit unsigned integer, declared with unsigned int i:2, it is pure binary, with no sign bit. With this interpretation, the bits 11 represent 3.
The program below shows that setting a signed two-bit integer to −1 or an unsigned two-bit integer to 3 produce the same bit pattern in the union, at least in your C implementation.
#include <stdio.h>
int main(void)
{
union Example
{
unsigned u;
int i : 2;
int j : 9;
unsigned int k : 2;
} ex;
ex.u = 0;
ex.i = -1;
printf("ex.i = -1: %#x.\n", ex.u);
ex.u = 0;
ex.j = 15;
printf("ex.j = 15: %#x.\n", ex.u);
ex.u = 0;
ex.k = 3;
printf("ex.k = 3: %#x.\n", ex.u);
}
Output:
ex.i = -1: 0x3.
ex.j = 15: 0xf.
ex.k = 3: 0x3.
Note that a compiler could also allocate the bits high-to-low instead of low-to-high, in which case the high bits of j would overlap with i, instead of the low bits. Also, a compiler could use different sizes of storage units for the nine-bit j than it does for the two-bit i, in which case their bits might not overlap at all. (For example, it might use a single eight-bit byte for i but use a 32-bit word for j. The eight-bit byte would overlap some part of the 32-bit word, but not necessarily the part used for j.)
Example1
#include <stdio.h>
union Example
{ int i:2;
int j:9;
};
int main(void)
{
union Example ex;
ex.j=15;
printf("%d",ex.i);
printf("\nSize of Union : %lu\n" , sizeof(ex));
return 0;
}
Output:
-1
Size of Union : 4
Observations:
From this ouput, We can deduce that even if we use 9 bits( max ), Compiler allocates 4 byte(because of padding).
Statement union Example ex; allocates 4 bytes of memory for Union Example object ex.
Statement ex.j=15; asigns 0x0000000F to that 4 Byte of memory. So for j it allocates 0-0-0-0-0-1-1-1-1 for 9 bits.
Statement printf("%d",ex.i); tries to print ex.i( which is 2 bits). We have 1-1 from the previous statement.
Here comes the interesting part, ex.i is of type signed int. Hence first bit is used to assign signed representation and most cpu does signed representation in 2's complement form.
So if we does reverse 2's complement of 1-1 we will get value 1. So the ouput we get is -1.
Example2
#include <stdio.h>
union Example
{ unsigned int i:2;
int j:9;
};
int main(void)
{
union Example ex;
ex.j=15;
printf("%d",ex.i);
return 0;
}
Output:
3
Observations:
Statement union Example ex; allocates 4 bytes of memory for Union Example object ex.
Statement ex.j=15; asigns 0x0000000F to that 4 Byte of memory. So for j it allocates 0-0-0-0-0-1-1-1-1 for 9 bits.
statement printf("%d",ex.i); tries to print ex.i( which is 2 bits). We have 1-1 from the previous statement.
Same as Above example but here ex.i is of type unsigned int. Hence no signed bit is used here for representation.
So whatever is stored in the 2 bit location is the exact value. Hence the ouput is 3.
Hope i cleared your doubt. Please check for 2's and 1's complement in the internet.

struct representation in memory on 64 bit machine

For my curiosity I have written a program which was to show each byte of my struct. Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <limits.h>
#define MAX_INT 2147483647
#define MAX_LONG 9223372036854775807
typedef struct _serialize_test{
char a;
unsigned int b;
char ab;
unsigned long long int c;
}serialize_test_t;
int main(int argc, char**argv){
serialize_test_t *t;
t = malloc(sizeof(serialize_test_t));
t->a = 'A';
t->ab = 'N';
t->b = MAX_INT;
t->c = MAX_LONG;
printf("%x %x %x %x %d %d\n", t->a, t->b, t->ab, t->c, sizeof(serialize_test_t), sizeof(unsigned long long int));
char *ptr = (char *)t;
int i;
for (i=0; i < sizeof(serialize_test_t) - 1; i++){
printf("%x = %x\n", ptr + i, *(ptr + i));
}
return 0;
}
and here is the output:
41 7fffffff 4e ffffffff 24 8
26b2010 = 41
26b2011 = 0
26b2012 = 0
26b2013 = 0
26b2014 = ffffffff
26b2015 = ffffffff
26b2016 = ffffffff
26b2017 = 7f
26b2018 = 4e
26b2019 = 0
26b201a = 0
26b201b = 0
26b201c = 0
26b201d = 0
26b201e = 0
26b201f = 0
26b2020 = ffffffff
26b2021 = ffffffff
26b2022 = ffffffff
26b2023 = ffffffff
26b2024 = ffffffff
26b2025 = ffffffff
26b2026 = ffffffff
And here is the question:
if sizeof(long long int) is 8, then why sizeof(serialize_test_t) is 24 instead of 32 - I always thought that size of struct is rounded to largest type and multiplied by number of fields like here for example: 8(bytes)*4(fields) = 32(bytes) — by default, with no pragma pack directives?
Also when I cast that struct to char * I can see from the output that the offset between values in memory is not 8 bytes. Can you give me a clue? Or maybe this is just some compiler optimizations?
On modern 32-bit machines like the SPARC or the Intel [34]86, or any Motorola chip from the 68020 up, each data iten must usually be ``self-aligned'', beginning on an address that is a multiple of its type size. Thus, 32-bit types must begin on a 32-bit boundary, 16-bit types on a 16-bit boundary, 8-bit types may begin anywhere, struct/array/union types have the alignment of their most restrictive member.
The total size of the structure will depend on the packing.In your case it's going as 8 byte so final structure will look like
typedef struct _serialize_test{
char a;//size 1 byte
padding for 3 Byte;
unsigned int b;//size 4 Byte
char ab;//size 1 Byte again
padding of 7 byte;
unsigned long long int c;//size 8 byte
}serialize_test_t;
in this manner first two and last two are aligned properly and total size reaches upto 24.
Depends on the alignment chosen by your compiler. However, you can reasonably expect the following defaults:
typedef struct _serialize_test{
char a; // Requires 1-byte alignment
unsigned int b; // Requires 4-byte alignment
char ab; // Requires 1-byte alignment
unsigned long long int c; // Requires 4- or 8-byte alignment, depending on native register size
}serialize_test_t;
Given the above requirements, the first field will be at offset zero.
Field b will start at offset 4 (after 3 bytes padding).
The next field starts at offset 8 (no padding required).
The next field starts at offset 12 (32-bit) or 16 (64-bit) (after another 3 or 7 bytes padding).
This gives you a total size of 20 or 24, depending on the alignment requirements for long long on your platform.
GCC has an offsetof function that you can use to identify the offset of any particular member, or you can define one yourself:
// modulo errors in parentheses...
#define offsetof(TYPE,MEMBER) (int)((char *)&((TYPE *)0)->MEMBER - (char *)((TYPE *)0))
Which basically calculates the offset using the difference in address using an imaginary base address for the aggregate type.
The padding is generally added so that the struct is a multiple of the word size (in this case 8)
So the first 2 fields are in one 8 byte chunk. The third field is in another 8 byte chunk and the last is in one 8 byte chunk. For a total of 24 bytes.
char
padding
padding
padding
unsigned int
unsigned int
unsigned int
unsigned int
char // Word Boundary
padding
padding
padding
padding
padding
padding
padding
unsigned long long int // Word Boundary
unsigned long long int
unsigned long long int
unsigned long long int
unsigned long long int
unsigned long long int
unsigned long long int
unsigned long long int
Has to do with alignment.
The size of the struct is not rounded to the largest type and multiplied by the fields. The bytes are aligned each by their respective types:
http://en.wikipedia.org/wiki/Data_structure_alignment#Architectures
Alignment works in that the type must appear in a memory address that is a multiple of its size, so:
Char is 1 byte aligned, so it can appear anywhere in memory that is a multiple of 1 (anywhere).
The unsigned int is needs to start at an address that is a multiple of 4.
The char can be anywhere.
and then the long long needs to be in a multiple of 8.
If you take a look at the addresses, this is the case.
The compiler is only concerned about the individual alignment of the struct members, one by one. It does not think about the struct as whole. Because on the binary level a struct does not exist, just a chunk of individual variables allocated at a certain address offset. There's no such thing as "struct round-up", the compiler couldn't care less about how large struct is, as long as all struct members are properly aligned.
The C standard says nothing about the manner of padding, apart from that a compiler is not allowed to add padding bytes at the very beginning of the struct. Apart from that, the compiler is free to add any number of padding bytes anywhere in the struct. It could 999 padding bytes and it would still conform to the standard.
So the compiler goes through the struct and sees: here's a char, it needs alignment. In this case, the CPU can probably handle 32 bit accesses, i.e. 4 byte alignment. Because it only adds 3 padding bytes.
Next it spots a 32 bit int, no alignment required, it is left as it is. Then another char, 3 padding bytes, then a 64 bit int, no alignment required.

Resources