Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is a.b always (&a)->b?

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?

like image 373
rwallace Avatar asked Jul 05 '20 23:07

rwallace


1 Answers

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”.
like image 62
Eric Postpischil Avatar answered Oct 28 '22 14:10

Eric Postpischil