Reputation: 380
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.
Upvotes: 4
Views: 192
Reputation: 23226
Given that your example varibles are actually int
:
int varA;
int varB;
int varC;
Without using the GCC compiler versions 4.4.7 or newer and using stdio.h
as noted in comments, the code does not compile, the second two of your statements will error out because of illegal types 'int' and 'pointer to int'
varA = *(int*)(&test); // The way it is done in the source code
varB = *(&test);//error
varC = test; //error
If they were int *
int *varA;
int *varB;
int *varC;
Then the first statement: varA = *(int*)(&test);
would error out.
The only way the assignment statements will compile is with the variables declared as follows:
int varA;
int *varB;
int *varC;
varA = *(int*)(&test); // The way it is done in the source code
varB = *(&test);
varC = test;
Upvotes: 1
Reputation: 16117
varA = *(int*)(&test);
means interpret the bitwise representation of test
as an int
, then store it in var
.
The cast, (int *)
, indicates that the bitwise representation of test
should be interpreted as an int
, while the *
operator interprets it as an int
.
This is identical to memcpy(&varA, &test, sizeof varA);
, if sizeof (int) == sizeof (int *)
.
Upvotes: 0
Reputation: 180978
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
.
Upvotes: 6
Reputation: 4023
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.
Upvotes: 1