1

With some friends we discuss about the corectness of this simple following code in ANSI C.

#include <stdio.h>

int main(void)
{
    int a=2;
    printf("%d", *&a);
    return 0;
}

The main discuss is about *&. If * access a memory location (aka pointer) and & gives memory address of some variable... I think * tries to access a int value as memory adress ( that obviously don't work), but my friend says *& it cancels automatically ( or interpret as &*). We tested it with GCC 4.8.1 (MinGW) and the code avobe worked it well... I think was not right.

What do you think about? Think there's a bad workaround here ( or this is just stupidity?). Thanks in advice :)

ruakh
  • 175,680
  • 26
  • 273
  • 307
elsemieni
  • 73
  • 9
  • Sure... I know one can reduce it, but that's why I'm asking this. In some specific memory cases can cause some bad compiler interpretations. – elsemieni Oct 10 '14 at 21:29
  • 1
    You might be thinking of the potential issue with combining the operators in the order `&*` which has been discussed on SO several times, including a detailed answer here: http://stackoverflow.com/a/2896975/12711 – Michael Burr Oct 10 '14 at 21:33

4 Answers4

3

a is an lvalue: the variable a.
&a is a pointer to this lvalue.
*&a is the lvalue being pointed to by &a — that is, it is a.

Technically speaking, *&a and a are not completely equivalent in all cases, in that *&a is not permitted in all circumstances where a is (for example, if a is declared as register), but in your example, they are completely the same.

ruakh
  • 175,680
  • 26
  • 273
  • 307
  • Interesting. Good to know that *& can cause bad interpretations in specific variable-type cases. ;) Thanks! – elsemieni Oct 10 '14 at 21:33
  • 3
    There are no bad interpretations. It's just that `&a` may not be meaningful, may not be allowed. Not a problem with interpretation. – David Heffernan Oct 10 '14 at 21:34
  • 1
    Conversely, `*&a` may be valid where `a` is not: If that is the only time the address of `a` is taken, it was not initialized, and there are no trap-representations for its type, that's enough to make it valid with arbitrary value, instead of undefined behavior. – Deduplicator Oct 10 '14 at 21:46
2

There is an interesting excerpt from C standard (as a footnote), namely C11 §6.5.3.2/4 (footnote 102, emphasis mine), which discusses this aspect directly:

Thus, &*E is equivalent to E (even if E is a null pointer), and &(E1[E2]) to ((E1)+(E2)). It is always true that if E is a function designator or an lvalue that is a valid operand of the unary & operator, *&E is a function designator or an lvalue equal to E. If *P is an lvalue and T is the name of an object pointer type, *(T)P is an lvalue that has a type compatible with that to which T points.

In your case a is a (modifiable) lvalue, that reflects to E symbol from standard and it's valid operand of the & operator as standard requires, thus *&a (i.e. *&E) is an lvalue equal to a.

Note that you can't take address of register storage class variable (as pointed by @Deduplicator), so it does not qualify into such reduction (that is, even as modifiable lvalue).

Grzegorz Szpetkowski
  • 36,988
  • 6
  • 90
  • 137
1

So long as *&a is meaningful, then *&a and a are the same thing and are interchangeable.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
1

In general, *&a is the same as a.

Still, there are corner-cases:

  1. *& may be invalid because &a is not allowed, as it is not an lvalue or it is of register-storage-class.

  2. Using a may be Undefined Behavior, because a is an uninitialized memory-less variable (register or auto-storage-class which might have been declared register (address was never taken)).

Applying that to your case, leaving out *& does not change anything.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118