Arrow operator in c
ELI5: arrow operator in c++
pointers - Arrow operator (->) usage in C - Stack Overflow
history - Why did C use the arrow (->) operator instead of reusing the dot (.) operator? - Retrocomputing Stack Exchange
Videos
I get this is a bit specific but I keep on seeing the arrow operator in my uni work and I really don't know how or when to use it no matte how much I try
foo->bar is equivalent to (*foo).bar, i.e. it gets the member called bar from the struct that foo points to.
Yes, that's it.
It's just the dot version when you want to access elements of a struct/class that is a pointer instead of a reference.
struct foo
{
int x;
float y;
};
struct foo var;
struct foo* pvar;
pvar = malloc(sizeof(struct foo));
var.x = 5;
(&var)->y = 14.3;
pvar->y = 22.4;
(*pvar).x = 6;
That's it!
Some of the first C code I saw was like this: 0x8040->output = 'A'; — its purpose was accessing memory mapped I/O locations. Needless to say it took me a while to figure out what this code was supposed to do, and the hex constant there really threw me.
The original K&R C placed all field names (here output) into the same namespace. It was an error to have two fields of the same name in different structs at different offsets — but ok to have the same name at the same offset, the idea here being that two different structs could share the same initial fields, giving cheap way of doing "subclassing" to put varying data members at the end of the struct.
A struct could also be anonymous, e.g. no tag name for the struct. None the less, the members could still be used in . or -> expressions.
The C Programming Language (K&R C) Appendix A, p197,209
[8.5] ... Two structures may share a common initial sequence of members; that is, the same member may appear in two different structures if it has the same type in both and if all previous members are the same in both. (Actually, the compiler checks only that a name in two different structures has the same type and offset in both, but if the preceding members differ the construction is nonportable.)
...
[14.1] ... §7.1 says that in a direct or indirect structure reference (with . or ->) the name on the right must be a member of the structure named or pointed to by the expression on the left. To allow an escape from the typing rules, this restriction is not firmly enforced by the compiler. In fact, any lvalue is allowed before ., and the lvalue is then assumed to have the form of the structure of which the name on the right is a member. Also, the expression before a -> is required only to be a pointer or an integer. If an integer, it is taken to be the absolute address, in machine storage units, of the appropriate structure.
Since the K&R language and compiler didn't care what the type of the left hand side of . and -> was, the only way it had to tell the difference was by having the two operators.
The ANSI C line of standards simply followed suit in syntax, even as these old rules were abandoned.
In the embryonic form of C described in the 1974 C Reference Manual, there was no requirement that the left operand of . actually be a structure, nor that the left operand of -> actually be a pointer. The -> operator meant "interpret the value of the left operand as a pointer, add the offset associated with the indicated structure member name, and dereference the resulting pointer as an object of the appropriate type. The . operator effectively took the address of the left operand and then applied ->.
Thus, given:
struct q { int x, y; };
int a[2];
the expressions a[0].y and a[0]->y would be interpreted in a fashion equivalent to ((struct q*)&a[0])->y and ((struct q*)a[0])->y, respectively.
If the compiler had examined the type of the left operand to the . operator, it could have used that to select between the two behaviors for it. It was probably easier, however, to have two operators whose behaviors didn't depend upon the left operand's type.