Maybe I confused people with my example. I was trying to understand a part of the code and simplyfied it. Here is part of the original code (simplyfied again... :)) (see original post below).
uint16_t hal_nrf_read_multibyte_reg(uint8_t *pbuf)
{
uint8_t memtype;
memtype = *(uint8_t*)(&pbuf);
if (memtype == 0x00U)
{
uint8_t data *buf = (uint8_t data *)pbuf;
DOTHIS
}
if (memtype == 0x01U)
{
uint8_t xdata *buf = (uint8_t data *)pbuf;
DOTHAT
}
if (memtype == 0xFEU)
{
uint8_t pdata *buf = (uint8_t data *)pbuf;
DOSOMETHING
}
return SOMETHING;
}
void main()
{
uint8_t payload[3];
hal_nrf_read_multibyte_reg(payload);
while(1) { }
}
So I was wondering, why do they cast pbuf which already is of uint8_t. But I think I've got my answer now.
------------ OLD POST -------------
I'm exploring Nordic Semiconductors nRF24LE1.
If I have the following test code.
void tempF(int *test)
{
int varA;
int varB;
int varC;
varA = *(int*)(&test); // The way it is done in the source code
varB = *(&test);
varC = test;
printf("A: %x\n", varA);
printf("B: %x\n", varB);
printf("C: %x\n", varC);
printf("C1: %x\n", test);
if (test == 0x00)
printf("equals 0x00");
}
int main(void) {
int myArray[3];
tempF(myArray);
return 0;
}
The printfs all give the same reply. What is the reason for doing it "varA-style"? Examples where it is necessary?
If I use the way in varA I don't get the warning "Warning C260: '=': pointer truncation.
Your three samples are all basically converting a pointer into an int. Technically, this requires a cast in your cases B and C, and your compiler ought to warn you about that. For example:
int varC = (int) test;
With the cast, that is completely valid, but without, not. Nevertheless, your compiler probably produces the same code with or without.
In your example code, however, the type of the expression &test is int **. Casting an expression of that type to int * and dereferencing the result, as is done to assign a value to varA, is intended to have the effect of reinterpreting the bytes of test as those of an int, as with a C++ reinterpret_cast. This does not necessarily produce the same value as converting test directly to an int, as is done to assign a value to varC. They are especially prone to differ if the size of a pointer is not the same as the size of an int on the target system, but they are not required to produce the same result even if the sizes are the same.
On the other hand, applying the * operator directly to the result of the & operator has no net effect, so the value computed for varB will reliably be the same as that computed for varC.
The problem is that any pointer type need not be of same size as an int. The compiler truies to warn you about that fact.
Using (int *)(&test) casts the address of test to be a pointer to int.
Dereferencing this yields an int that happily can be assigned to an int variable. It may still be truncated if pointers need more bits than an int can hold, but you convinvced the compiler that you do know what you are doing and it happens by purpose.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With