lev.1 code
lev.1 code

Reputation: 87

The behavior of unary & operator when met []

I've been reading C11 6.5.3.2 p3

The unary & operator yields the address of its operand. If the operand has type “type”, the result has type “pointer to type”. If the operand is the result of a unary * operator, neither that operator nor the & operator is evaluated and the result is as if both were omitted, except that the constraints on the operators still apply and the result is not an lvalue. Similarly, if the operand is the result of a [] operator, neither the & operator nor the unary * that is implied by the [] is evaluated and the result is as if the & operator were removed and the [] operator were changed to a+ operator. Otherwise, the result is a pointer to the object or function designated by its operand.

I can't understand most of this paragraph although reading it repeatedly.
My problem parts are * that is implied by the [], []operator were changed to a + operator, function designated by this operand. This paragraph is talking about & but why does * appear and term "function designated" appear after saying []. And [] operator were changed to a + operator seems trying to say the definition of array : E1[E2] = *((E1) + (E2)) What does these lines mean? I need some help.

Upvotes: 2

Views: 186

Answers (2)

Eric Postpischil
Eric Postpischil

Reputation: 223747

[From a comment] I can't sure []'s meaning. It's not written as array[i] just [].

The C standard uses [] to mean the subscript operator. Although it appears in source code as E1[E2], where E1 and E2 stand for expressions, the [ and ] characters are the fundamental way it is recognized, and they designate an operation of array subscripting.

[C 2011, draft N1570, 6.5.3.2 3, discussing the unary & operator] … Similarly, if the operand is the result of a [] operator, neither the & operator nor the unary * that is implied by the [] is evaluated and the result is as if the & operator were removed and the [] operator were changed to a + operator. Otherwise, the result is a pointer to the object or function designated by its operand.

Going back to the [] operator, consider an expression E1[E2]. The definition of the subscript operator, in 6.5.2.1 2, is that it is identical to (*((E1)+(E2))). (In other words, it takes the pointer E1 and adds the subscript E2 to it, then applies * to get the element at that location. Or, since + is commutative, E2 can be the pointer, and E1 can be the subscript.) So “the unary * that is implied by the []” is that * in (*((E1)+(E2))).

So, when we have & applied to E1[E2], this passage tells us to consider it as &(*((E1)+(E2))) and that neither the & nor the * are evaluated, so it is as if it were ((E1)+(E2)).

… why does … [the] term "function designated" appear…

The sentence containing “function designated” is separate. The “Otherwise” tells us it is talking about the situation other than when & is applied to a subscript expression (from the sentence before) or to a unary * expression (from two sentences before). So we just have &E, where E is something other than *E1 or E1[E2]. This sentence says “Otherwise, the result is a pointer to the object or function designated by its operand.” If E is an object, then &E is a pointer to the object. If E is a function, then &E is a pointer to the function.

Upvotes: 2

Petr Skocik
Petr Skocik

Reputation: 60117

If the operand is the result of a unary * operator, neither that operator nor the & operator is evaluated and the result is as if both were omitted, except that the constraints on the operators still apply and the result is not an lvalue.

Unary & applied to the result of unary *, cancels the * and converts the operand of the original * to an r-value:

#include <assert.h>
int main()
{
    int *p=&(int){42};
    assert(&*p == p); //the value (42) is not fetched from the target
    #if 0
        &*p = &(int){1000}; //not OK; & cancels the * but converts p to an r-value (can't be on the left-hand side of an assignment)
    #endif
    p = &(int){1000}; //ok; p is an l-value (can be on the left hand side of an assignment)
    //(more accurately: can have its address taken)
}

Now since a pointerOrArray[index] expression is defined (6.5.2.1p2) as *(pointerOrArray+index) (the result of a unary *, except the * is hidden), you can apply the same rule to it: &pointerOrArray[index] <=> (pointerOrArry+Index). That's what your first quoted sentence says.

The last sentence you quoted can be (within the context of 6.5.3.2p3) interpreted as:

Otherwise (if unary & isn't combined with * or []), the result (of unary &) is a pointer to the object (&object) or function (&function) designated by its operand (an object or a function).

Upvotes: 3

Related Questions