Neon Flash
Neon Flash

Reputation: 3233

Type Casting Pointer in C

I am going through a C Code and wanted to know if I have understood the code correctly or not.

There is a structure, BF_salt defined in the header file as shown below:

typedef
{
BF_WORD salt[4];
..
..
} BF_SALT;

In the main C Code, there is a call to a function:

function func1()
{
 static BF_SALT salt;
 func2(salt.salt,x,y);
....
}

func2(BF_WORD * dst,x,y)
{
 unsigned char * dptr= (unsigned char*)dst;
 int c1,c2;

 // c1 and c2 are initialized here.

 // in a loop, an operation similar to the below is performed.

 *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
}

My understanding of the code above is:

in func1, salt is defined with data type of structure BF_SALT.

we are calling func2, passing the salt field of the structure.

the salt field is an array of 4 elements, each of data type BF_WORD (32 bit word or 4 bytes)

in func2

dst is the name of the array which points to an element of type BF_WORD.

it is performing a typecast on the pointer, dst.

currently, dst is pointing to data type BF_WORD. it is type casted so that it points to a char (1 byte data).

now it is performing bitshift operations on the integers, c1 and c2 and writing the output to the memory address pointed by dptr. So, it is overwriting the data which was initially pointed to by dst (the bytes in the salt array).

c1 and c2 are of datatype int, which requires 4 bytes of space.

In what way will dptr overwrite the contents of the array? Since everytime, we do *dptr++, we are advancing the pointer, dptr by 1 byte because it points to a character.

however, we are assigning it a value of size greater than 1 byte. How will the data be written to memory?

Thanks.

Upvotes: 1

Views: 871

Answers (3)

alk
alk

Reputation: 70981

Here

*dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);

an implicit cast to unsigned char is performed, as dptr is of type unsigned char *, so *dptr is treated as an unsigned char.

Upvotes: 1

Alex Celeste
Alex Celeste

Reputation: 13380

Only the lowest byte of the result will be written to memory. Since the pointer is to a char, the int will be truncated and the higher bytes will be lost as it is converted to the type of the lvalue; the same rule as if you had simply assigned the result to a char variable. See standard sections 6.3.2.1 and 6.5.16.1 for the details.

Upvotes: 2

Barath Ravikumar
Barath Ravikumar

Reputation: 5836

Your understanding of the above code , is similiar to mine , and also let me chip in some of my own thoughts

unsigned char * dptr= (unsigned char*)dst;

Here dst which is of type BF_WORD (4 bytes) , is down casted to a char type (1 byte) Also it is worth noting that , though the type of pointer is char , and can navigate one byte at a time , it does holds the address of a 4 byte contiguous memory location , so technically it must be ably to navigate those 4 bytes , a byte at a time.

In what way will dptr overwrite the contents of the array?

dptr now contains the starting address of the 4 number , 4 byte array salt. So it currently accesses salt[0]. Here salt[0] is 4 bytes in size , and dptr is 1 byte pointer , so it takes four (dptr++) increments to cover one element of the array salt[0].

Now the other question

we are assigning it a value of size greater than 1 byte. How will the data be written to memory?

*dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);

Here both c1 and c2 are of type int , so after the bitwise operation the result is of type int. Hence the 4 byte result is written to salt[0] pointed by dptr; In the next increment of dptr , the pointer will point to the 2 byte of the previous 4 byte result , so the last three bytes of the previous result will be overrun by the next bitwise result.

Upvotes: 0

Related Questions