How does the C/C++ compiler distinguish the uses of the * operator (pointer, dereference operator, multiplication operator)?
Asked Answered
C

2

11

How, in C and C++ languages, can the compiler distinguish * when used as a pointer (MyClass* class) and when used as a multiply operator (a * b) or when is a dereferencing operator (*my_var)?

Cinthiacintron answered 8/10, 2020 at 7:28 Comment(5)
Wikipedia has an article on the classic method: lexer hack.Figurehead
@Figurehead at least in case of gcc that's no longer a thing. C++ is complex enough that classic lexers are inept. G++ uses a hand-written recursive descent parser ( so something similar to what was put into basis of Google translator) instead of bison-based one. But in general it depends on compiler implementation and only few expose that secretSouvaine
The same way the compiler distinguishes a & b and &var, +a and a + b, or &&a and a && b: one is a unary and the other is a binary operator. In C++/CLI there are also type ^ vs a ^ b and type % vs a % bHusain
@Swift-FridayPie gcc and clang are open source so there are hardly any secrets hereRiddick
There is no actual ambiguity to resolve. It is alway clear from the grammar whether a unary or binary operator is intended, and it is always clear from the current parse context whether a declaration or a dereference is being written.Astilbe
M
20

It depends from the context in which it is used, for a simple resolution it looks at the left and right word to understand what a symbol is.

The language's syntax is defined by a tree of grammatical productions that inherently imbue a priority or "precedence" to the application of certain operators over the application of other operators. This is particular handy when an expression might otherwise be ambiguous (because, say, two operators used are represented by the same lexical token).

But this is just lexing and parsing. Whether any particular operation is actually semantically valid is not decided until later in compilation; in particular, given two pointers x and y, the expression *x *y will fail to compile because you cannot multiply *x by y, not because there was a missing operator in what might otherwise have been a dereference followed by another dereference.

Further read at wikipedia page: Lexer_hack.

Other interesting read at this Lexer-Hack Enacademic link.

Melisandra answered 8/10, 2020 at 7:34 Comment(0)
T
5
  • deferencing * operator is an unary operator so in trivial cases compiler will apply an implicit rule. eg
int a;
int *ptr = &a;
*ptr = 5;
  • multiplication operator * is a binary operator so in trivial cases compiler will apply multiplication provided the operands support it eg:
int a;
int b;
int c = a*b;
  • For more complex operations you might need to help the compiler understand what you mean by using parenthesis if the operators precedence is not enough eg:
  int a = 1;
  int b[2] = {2,3};
  int *aPtr = &a;
  int *bPtr = b;
  
  int c = *aPtr * *(bPtr+1);
Taitaichung answered 8/10, 2020 at 7:42 Comment(2)
So don't say that if it's not true ;-). Typically for function pointers you need parentheses because the operator()() has precedence over operator*(), but that is not *-specific. In particular, it is not necessary in order to prevent confusion between dereferencing and multiplication.Fike
Yeah, it does; but again, there is no danger of confusion between the different semantics of the asterisk. I suppose that confusion is impossible because you cannot multiply pointers (I bet you you could in early -- pre-ANSI -- versions of C).Fike

© 2022 - 2024 — McMap. All rights reserved.