In C, a.b
is normally synonymous with (&a)->b
.
Is this true in absolutely all cases, even if a
is a macro for some messy compound term? Or are there any edge cases, in any version of C, in which the equivalence fails to hold?
Here are three counterexamples, all based on constraints on applying &
:
a
is an rvalue because it is a structure returned by a function:
int bar(void)
{
extern struct S { int b; } foo(void);
return (&foo())->b;
}
Clang says “error: cannot take the address of an rvalue of type 'struct S'”. But it accepts return foo().b;
.a
is an rvalue because it is the result of an assignment:
int bar(void)
{
struct S { int b; } x = {0};
struct S y;
return (&(y=x))->b;
}
Clang says “error: cannot take the address of an rvalue of type 'struct S'”. But it accepts return (y=x).b;
.a
is declared with register
, so its address may not be taken:
int bar(void)
{
register struct S { int b; } a = {0};
return (&a)->b;
}
Clang says “error: address of register variable requested”.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