c - Size of different data types causes confusion -
i working on c programs , had confusion lately, hit me again: suppose have function takes 32 bit size variable, , takes 8 bits, , have transfer data 32 bit variable 8 bit variable.
here sample program have confusion with:
#include <stdio.h> #define size_of_block 512 uint32* = null; // read uint8* b = null; // write int read_register(uint32* rbuff) { uint8 i; (i = 0; < size_of_block / 4; i++) // here 1 rbuff[i] = read_from_32_bit_reg(); // read incrementally on each iteration return 0; } int write_register(uint8* wbuff) { uint8 i; (i = 0; < size_of_block; i++) // here 1 write_reg(wbuff[i]); // point 2 return 0; } int main() { = (uint32*)malloc(sizeof(uint32) * 128); // contains 4096 bits b = (uint8*)malloc(sizeof(uint8) * 512); // contains 4096 bits read_register(a); b = (uint8*)a; // point 1 write(0x0080000, b); free(a); free(b); return 0; }
1) 512 bits in 128, 4 byte locations. if assign value 8 bit location, side of bits stripping off? msb 8 bits, or lsb 8 bits on intel pc.
2) still transferring 4096 bits, , 'b' have address of a's addressed location. still transferring correct values a?
its confusion, , couldn't make mind, how approach it.
p.s. term called narrowing if things same way did, assigning address 32 bit variable 8 bit variable, , goes through on 8 bit increments, should able values? don't think narrowing happens in pointer variable case, both int size?
first remark: when use bits in
a = (uint32 *)malloc(sizeof(uint32)*128);//contains 512 bits
you wrong: should have written ...//contains 512 bytes
then have 2 ways of passing integer types of 1 size smaller size:
by conversion:
uint32_t = 259; uint8_t b = a; // defined unsigned types: retains low order bits here 3
formally n1256 draft c99 standard says:
otherwise, if new type unsigned, value converted repeatedly adding or subtracting 1 more maximum value can represented in new type until value in range of new type
by aliasing (type punning):
uint32_t = 259; uint8_t b = *((uint8_t) &a); // lsb on intel 3 0 on big endian system
a pointer object can converted pointer char (or unsigned char).
uint8_t
canunsigned char
(*), pointer conversion valid , return in sequence bytes of representation ofuint32_t
... value implementation dependent. intel pc uses 2's complement little endian architecture lsb, still3
. msb (0) on big endian architecture.but in general case, accessing value of 1 type non compatible type undefined behaviour meaning compiler free including commenting out offending line!
now points 1 , 2. in 1 assign pointer array of uint32_t
pointer uint8_t
. valid. in 2 use uint8_t
pointer access bytes of representation of uint32_t
values of original array. still valid, , able rebuild original values bytes, bytes values implementation dependent.
a last remark unrelated question: when assign pointer obtained malloc
new value, without saving or freeing first, loose possibility later free it, causing memory leak. here have:
b = (uint8 *)malloc(sizeof(uint8 )*512);//contains 512 bits ... b = (uint8 *)a;// memory leak!
(*) char
required able represent values of ascii alphabet, needs @ least 7 bits , types must have size multiple of char
size. if uint8_t
type exists must synonym unsigned char
.
Comments
Post a Comment