Structure pointer operator conjecture (theory)

2019-05-25 07:24发布

问题:

Pointers to structures are used so often that there is a special operator for it: ->. The below expressions are equivalent:

(*x).y
 x->y

Would it be fair to think of this operator simply as preprocessor macro defined as such:

#define (x)-> (*(x).)

Why or why not? Or was it coded as a operator from the start - and how would this be different / advantageous?

Just curious.

回答1:

The below expressions are equivalent:?

(*x).y
 x->y

Yes, Both are two different ways to access structure member y.

(*x).y operator is . DOT that works with value variable Element selection by reference. that the reason * used. means x is pointer to struct.

x->y operator -> is used called Element selection through pointer. This work with pointer to struct. that is the reason * not used this time.

Both works same.

Would it be fair to think of this operator simply as preprocessor macro defined as such:

#define (x)-> (*(x).)

No First it give an error: macro names must be identifiers. This error is because we can't have -> operator as macro name.

a valid macro name can be:

Macro names should only consist of alphanumeric characters and underscores, i.e. 'a-z', 'A-Z', '0-9', and '_', and the first character should not be a digit. Some preprocessors also permit the dollar sign character '$', but you shouldn't use it; unfortunately I can't quote the C standard since I don't have a copy of it.

Also, note -> and . are differences operators as I state above. also their precedence are different so its bad idea to replace one operator with other.

Valid macros to access struct elements:

Additionally I would like to share today only i came to know that most C header files. Defined macros like:

#define S(x)  ((x).y)

for specific strcut element.

Notice (x) parenthesis around x is to overwrite precedence of * over . . By default . DOT has higher precedence over * So that it can be use for pointer and simple variable. Below my example will be helpful I think.

#define S(x)  ((x).y)
typedef struct {
 int y;
}X;
X *x;
X b;
int main(){
 S(*x);
 S(b);     
}

EDIT:
Better Option

I am extending my idea to access strcut elements, I defined new macro:

#define S(x,y)  ((x).y)
typedef struct {
 int a;
}X;
X *x;
X b;
int main(){
 S(*x,a);
 S(b,a);
}

Not its not more for specif elements via macros.

Hope at-least OP love it :)



回答2:

Would it be fair to think of this operator simply as preprocessor macro defined as such:

No.

Why or why not?

The -> operator has some specific semantics that cannot be enforced with a macro (which is a simple text substitution). Namely, the left-hand operand must be a pointer to a struct or union type, and the right-hand operand must be a member of the struct or union type, and the result of the expression must be an lvalue. You cannot enforce those rules with a macro.



回答3:

Would it be fair to think of this operator simply as preprocessor macro defined as such:

No, it wouldn't.

Why or why not?

Because it's not a macro. It's a distinct operator defined in the language, that appears to be providing syntactic sugar for another functionality.