Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Behavior of & followed by * operator

I have a question about the behavior of the address-of operator followed by a dereference operator.

Let's take a look at the expression &*p where p is of type int *.

The C11 standard (section 6.5.3.2) says:

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.

With the footnote:

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. Among the invalid values for dereferencing a pointer by the unary * operator are a null pointer, an address inappropriately aligned for the type of object pointed to, and the address of an object after the end of its lifetime.

It is clear that &*p has to be equal to p except that &*p is not an lvalue.

If we now consider a with type int[10], what type is &*a? And should there be a difference between for example sizeof a and sizeof &*a?

On the one side if we evaluate &*a, a would decay to int * with the dereference operator it will become int and with the address-of operator then int *.

On the other side if &*a behaves "as if both were omitted" the type should be int[10].

A short example reveals that gcc treats the expression different:

#include <stdio.h>

int main(void)
{
    int a[10];

    printf("%zu\n%zu\n", sizeof a, sizeof &*a);

    return 0;
}

Output:

40
8

Is this in agreement with the C11 standard?

Maybe it is because the "constraints on the operators still apply" and the operand of the dereference operator has to be a pointer?

like image 797
Osiris Avatar asked Dec 06 '18 16:12

Osiris


People also ask

What are the 4 types of behavior?

A study on human behavior has revealed that 90% of the population can be classified into four basic personality types: Optimistic, Pessimistic, Trusting and Envious.

What is the meaning of behavior of a person?

Definition of behavior 1 : the way in which someone conducts oneself or behaves (see behave sense 1) We were grateful for the gracious behavior of our hostess. The children were rewarded for good behavior. Be on your best behavior.

What is behaviour and examples?

The definition of behavior is the way a person or thing acts or reacts. A child throwing a tantrum is an example of bad behavior. The actions of chimps studied by scientists are an example of behaviors.

Is the word behavior correct?

Behavior is the preferred spelling in American English. Behaviour is preferred everywhere else. Other than the spelling, there is no difference between the two words. The spelling distinction extends to all derivatives, including behaviors–behaviours, behavioral–behavioural, and behaviorally–behaviourally.


1 Answers

Consider that the conversion from array to pointer-to-first-element happens separately and before the application of *. Although the decision about whether to convert the array to a pointer is not made until the C implementation determines whether it is the operand of sizeof or & (per C 2018 6.3.2.1 3), this conversion is not part of the * operation. Thus, by the time we are examining &*, the operand must already be a pointer.

Furthermore, a constraint on the operand of the * operator is that it shall have pointer type (C 2018 6.5.3.2 2). Therefore, the operand must be a pointer, not an array.

The phrasing “the result is as if both were omitted” motivates us to consider what the result would be if both were omitted, but the text goes on to say “except that the constraints on the operators still apply and the result is not an lvalue.” Since the constraints still apply, the operand must be a pointer; it is not logically consistent that the constraint could apply and the operand could be an array that has not been converted to a pointer.

like image 116
Eric Postpischil Avatar answered Oct 04 '22 10:10

Eric Postpischil