&(*var)
evaluates to the same as var
in most circumstances, at compile time, but note some caveats:
var
should be a valid pointer, although there is not reason for the compiler to generate code to dereference it. Indeed C11 specifies that there is no undefined behavior for &*var
even if var
is a null pointer.
- as Pascal Cuoq commented,
var
should not be a pointer to void
, but the C Standard explicitly allows it for this very case... Shocking indeed.
- if
var
is an array, with more than one element, var
and &*var
have a different type and sizeof(var)
and sizeof(&(*var))
have a different value: the first is the size of the array while the second is the size of a pointer to the its first element.
- As commented by Peter, if
var
is an uninitialised pointer, then evaluating var == &(*var)
gives undefined behaviour (since evaluating either side of the ==
gives undefined behaviour - accessing the value of an uninitialised variable is what gives the undefined behaviour).
The example you link to in the question uses this construction for no purpose whatsoever:
#define WrdSiz 4
void getline_bin_float_vertex(int ddim, double *c, int *ref) {
int i;
float ff;
for (i = 0; i < ddim; i++) {
fread((unsigned char *)&(ff), WrdSiz, 1, stdin);
c[i] = ff;
}
fread((unsigned char *)&(*ref), WrdSiz, 1, stdin);
}
The programmer is reading a number of floating point values and an integer from a file redirected into the standard input. The code is awkward and non-portable:
- the size of
float
is silently assumed to be 4
- the size of
int
is silently assumend to be the same 4 bytes
c
must be a valid pointer, unless ddim
is 0
ref
must be a valid pointer as fread
will try and store 4 bytes at the address it points to, unless the stream is at end of file
- end of file and read errors are silently ignored and undefined behavior is possible.
The code can be simplified and protected this way:
#define WrdSiz 4
/* read values from stdin, return non-zero in case of failure */
int getline_bin_float_vertex(int ddim, double *c, int *ref) {
int i;
float ff;
assert(sizeof float == WrdSiz);
assert(sizeof int == WrdSiz);
assert(dim == 0 || c != NULL);
assert(ref != NULL);
for (i = 0; i < ddim; i++) {
if (fread(&ff, sizeof ff, 1, stdin) != 1)
return -1;
c[i] = ff;
}
if (fread(ref, sizeof(*ref), 1, stdin) != 1)
return -1;
return 0;
}
Other portions of this source code show poor or even invalid constructions, you should study this package only for examples of what not to do.