I have got two cases: -
CASE 1
void *data;
struct known_struct *var = data;
printf("%d", var->first_int);
CASE 2
void *data;
printf("%d", (struct known_struct*) data->first_int);
This second version is wrong -- the "->" operator binds more
tightly than the cast operator, so this must be written with
parentheses:
printf("%d", ((struct known_struct *)data)->first_int);
In case 1, we use a variable named 'var' to point to 'data'. And then
we access an integer named 'first_int' in the data pointed by var.
So, count a memory overhead (creating 'var' on stack), second is
assignment overhead (var = data).
In case 2, we have not used any extra variable.
We typecast 'data' into (struct known_struct*) and then access its
'first_int'.
So, this seems to me as no memory overhead and no assignment overhead.
So is there any extra hidden overhead due to this typecasting.
A cast (the syntax with the type name in parentheses) is, semantically
and essentially, just an assignment to a temporary variable whose
type is given by the cast. Thus, case 2 has an extra temporary
variable and assignment, just like case 1. For more, I refer you
to my longer answer from yesterday, but now that we have actual
sample code to test, let us find out which version generates which
instruction(s) using GCC on the Intel x86 platform:
% cat t.c
struct known_struct { int first_int; int second_int; };
int f1(void *data) {
struct known_struct *var = data;
return var->first_int;
}
int f2(void *data) {
return ((struct known_struct *)data)->first_int;
}
% cc -O2 -S -mregparm=3 -fomit-frame-pointer t.c
[The -mregparm and -fomit-frame-pointer generate smaller/faster
code, at the expense of some ABI compatibility and debug-ability;
I used this to eliminate the usual frame and stack access to
make the generated assembly code more obvious.]
% cat t.s
[edited to toss irrelevant junk]
f1:
movl (%eax),%eax
ret
f2:
movl (%eax),%eax
ret
Functions f1() and f2() produced identical code, consisting of a
single "movl" instruction with identical operands (plus of course
the required "ret"urn instruction). Which instruction do you think
is faster -- movl, or movl?