elsemieni
elsemieni

Reputation: 73

Cancellation of *& in ANSI C

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 :)

Upvotes: 1

Views: 528

Answers (4)

Deduplicator
Deduplicator

Reputation: 45684

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.

Upvotes: 1

Grzegorz Szpetkowski
Grzegorz Szpetkowski

Reputation: 37944

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).

Upvotes: 2

David Heffernan
David Heffernan

Reputation: 613412

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

Upvotes: 1

ruakh
ruakh

Reputation: 183504

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.

Upvotes: 3

Related Questions