5

Is operator -> allowed to use in C instead of .? Does its availability depend on compiler we are using? Is -> operator available in the last C standard or does it come from the C++ standard? How those two differ?

5 Answers5

14

In C, c->m is equivalent to (*c).m. The parentheses are necessary since . has a higher precedence than *. Any respectable compiler will generate the same code.

In C++, unless -> or * is overloaded, the equivalence is as above.

Community
  • 1
  • 1
Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • I don't think you are allowed to overload the `->` and `.`operators in C++? – Lundin Jan 29 '16 at 07:55
  • @Lundin `.`, not. `->`, definitely yes. – Angew is no longer proud of SO Jan 29 '16 at 07:56
  • @Lundin `->` is overloadable and Bjarne wants to make `.` overloadable as well for the C++17 in order to have smart references akin to smart pointers http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4477.pdf. – bolov Jan 29 '16 at 07:56
  • @Lundin: we'll split 50/50. You can't override `.`. – Bathsheba Jan 29 '16 at 07:56
  • Unless `->` *or `*`* is overriden. – Angew is no longer proud of SO Jan 29 '16 at 07:56
  • That's certainly true. You can override `*` as a dereference and as multiplication. See boost spirit. – Bathsheba Jan 29 '16 at 07:57
  • @Ludin sure -> can. smart pointers do it all the time. `.` cannot, along with `? :`, `.*`, `::`, `sizeof` and `typeid`. – Remus Rusanu Jan 29 '16 at 07:57
  • Well, wow. Overloading `->` or `.` seems severely brain-damaged to me... Allowing you to overload one of them but not the other even more so. Why would anyone want to do that?! Allowing it will mean it will get abused. – Lundin Jan 29 '16 at 08:00
  • 1
    C++ gives you the opportunity to shoot yourself in the foot. That's up to you. Overloading `->` *can* be useful when building managed pointer classes. My strongest dislike of Java is the fact that it doesn't allow operator overloading. I find working with some classes, e.g. `BigInteger` frustrating. – Bathsheba Jan 29 '16 at 08:03
  • 2
    @Lundin Overloading `->` is indeed *extremely* useful when creating a pointer-like class (think `std::unique_ptr`). On the other hand, you need *some* form of being guaranteed access to a member `y` or object `x` when you have `x`, so one operator needs to remain unoverloadable. And that's `.`. – Angew is no longer proud of SO Jan 29 '16 at 08:11
  • I really don't see how it would be "extremely useful" for anyone to open up the language for bugs like: `std::committee* member1, member2; member1->brainstorm(); member2->brainstorm();` – Lundin Jan 29 '16 at 08:37
  • 2
    @Bathsheba No, shoot yourself in the foot is C. C++ is blow your leg off :) Java is boring because there's no flashy explosions. – Lundin Jan 29 '16 at 08:40
5

There are 3 operators here, *, . and ->. This is important, because . and -> both have precedence 1, but * has precedence 2. Therefore *foo.bar is not the same as foo->bar and parenthesis are required, like in (*foo).bar.

All are original C operators and have been around forever.

Remus Rusanu
  • 288,378
  • 40
  • 442
  • 569
5

In C, a->b and (*a).b are 100% equivalent, and the very reason for introduction of -> into C was precedence—so that you don't have to type the parentheses in (*a).

In C++, operator * and operator -> can be overridden independently, so you can no longer say that a->b and (*a).b are equivalent in all cases. They are, however, 100% equivalent when a is of a built-in pointer type.

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
  • 1
    You are correct that they can be theoretically different. In practise, the only reason I can think of to make them different is as an entry in the International Obfuscate C++ Competition (A thing which has never happened - probably because there is no *challenge* to it.) – Martin Bonner supports Monica Jan 29 '16 at 08:04
  • 1
    @MartinBonner Or they can be different *by accident.* When looking for an elusive bug, it's good to know what can be absolutely taken for granted. Everything else is potentially suspicious. – Angew is no longer proud of SO Jan 29 '16 at 08:09
1

Operator -> is standard in C. Both . and -> allow to access a struct field. You should use . on a struct variable and -> on a struct pointer variable.

struct foo {
    int x;
    int y;
}

struct foo f1;
f1.x = 1;
f1.y = 3;
struct foo *f2 = &f1;
printf("%d\n", f1.x);     // 1
printf("%d\n", f2->x);    // 1

The * operator is called dereference operator and returns the value at the pointer address. So (*f2).x is equivalent to f2->x.

tano
  • 836
  • 1
  • 10
  • 25
0

In general case, yes - compiler should produce the same code for both. But these operators can be overloaded and thus have different functions.

Piotr Smaroń
  • 446
  • 3
  • 11