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