By 32 bit processor (more specifically speaking, It is talking about size of data bus rather than size of registers), It means 32 bits(4 Bytes) of data will be read and processed at a time.
Now, Consider an int:
int a=10; //assuming 4 bytes
00000000 000000000 00000000 00001010
Assuming little endian architecture, it would be stored as:
------------------------------------------------------------------------
| 00001010 | 00000000 | 00000000 | 00000000 | <something_else>
-------------------------------------------------------------------------
1st byte 2nd byte 3rd byte 4th byte
\--------------------------------------------------/
|
4 bytes processed together
In this case when the processor will read the data to be processed, It can process the entire integer in one go (all 4 bytes together)(In 1 machine cycle more strictly speaking)
However consider a case where the same integer was stored as,
------------------------------------------------------------------------
|<something_else>| 00001010 | 00000000 | 00000000 | 00000000 |
-------------------------------------------------------------------------
1st byte 2nd byte 3rd byte 4th byte
\------------------------------------------------------/
|
4 bytes processed together
In this case, the processor would need 2 machine cycles to read the integer.
Most of the architecture always try to minimize the CPU cycles.
Hence the 1st arrangement in memory is preferred by many compilers and thus enforce alignment requirements (padding).
So 4 byte int
s are stored in addresses starting at multiple of 4s, chars
are stored in multiple of 1s, 8 byte doubles
are stored in multiple of 8s, 8 byte long long int
in multiple of 8s and so on...
Now consider your structure
struct structure2
{
int id1; //assuming 4 byte int
char name; // 1byte
int id2; //4 byte
char c; // 1 byte
float percentage; //assuming 4 byte float
};
id1 will get stored in some address(starting multiple of 4)in memory and take 4 bytes.
name will take the next byte.
now if id2 gets stored in next byte, It will break the alignment rule above. So it would Leave 3 Bytes of padding and get stored starting with adress which is next multiple of 4 and will take 4 bytes.
For c again the same thing happens as name. It takes next 1 byte and keeps 3 byte of padding.
At last percentage gets stored in next 4 bytes.
So total size of structure becomes 20 bytes.
A more complicated case would be say
struct mystructure
{
char a; //1 byte char
double b; // 8 byte double
int c; // 4 byte int
}
Here one may at first glance say that size would be 20 bytes(1 byte for char + 7 byte padding + 8 byte for double + 4 byte for int).
However the actual size would be 24 bytes.
Say somebody declared an array of this structure
struct mystructre arr[4];
Here(assuming 20 byte structure) although arr[0] is properly aligned, but if you check carefully you'll find that arr[1].b is misaligned. So 4 bytes of extra padding is added at the end of structure to make the structure size multiple of its alignment.(Every structure also has its own alignment requirements).
Hence the total size would be 24 bytes.
The size of the integer,long etc. are decided by the compiler. The compiler generally takes care of the processor architecture but it may choose not to.
Similarly, whether to use padding or not is decided by the compiler. Not padding is known as packing. Some compilers have explicit options for allowing packing.
In GCC(GNU C compiler) you can do it with __attribute__((__packed__))
, so in the following code
struct __attribute__((__packed__)) mystructure2
{
char a;
int b;
char c;
};
mystructure2 has size 6 bytes because of explicit request to pack the structure. This structure will be slower to process.
You can probably figure it out yourself by now, what would happen in 64 bit processor, or if size of int was different.