2

I always thought that operators appear in expressions. But this reply seems to suggest that the asterisk in the declaration int *p; is an operator. Is this correct? If not, how is this asterisk called?

AlwaysLearning
  • 7,257
  • 4
  • 33
  • 68
  • No, it is not. It is a part of the type name. – Eugene Sh. Dec 23 '19 at 18:59
  • @EugeneSh. But is there a term for it? A type modifier? Something else? – AlwaysLearning Dec 23 '19 at 19:02
  • Looking for the right term now... – Eugene Sh. Dec 23 '19 at 19:03
  • 2
    I don't see a formal name. It is a part of a *declarator* syntax. That is, just a syntax element. – Eugene Sh. Dec 23 '19 at 19:09
  • I concur. The C specification indicates this as part of a *declarator.* It doesn't even call it an asterisk; it simply says "of the form `* type-qualifier-listopt D`". – Robert Harvey Dec 23 '19 at 19:11
  • That asterisk in a declaration has the same origin as the asterisk in a dereference operator. Per Kernighan and Ritchie 1978, page 90, declarators mimic expressions: `int *p` tells us that, when `*p` appears in an expression, it is an `int`. The declarator gives us a “picture” of an expression, and the asterisk in that picture portrays the dereference operator. But, because the compiler is parsing a declaration, how it interprets the text is different, and, for formal parsing purposes, it is not an operator. But these are technical differences; the common formation still exists. – Eric Postpischil Dec 23 '19 at 19:16
  • In the C++ grammar, the `*` that denotes a pointer being declared is called a *ptr-operator* (which actually covers `*`, `&`, `&&`, and a construct with a *nested-name-specifier*). – Eric Postpischil Dec 23 '19 at 19:17
  • https://stackoverflow.com/questions/33486504/clearly-stating-the-difference-betwen-and-as-part-of-a-type-and-as-a-derefer – bolov Dec 23 '19 at 19:31

3 Answers3

3
int *p;

THAT asterisk is not an operator, it qualifies the type. "Integer" vs "pointer to integer".

int foo;
int *bar = &foo; // not that one

*bar = 4; // THIS one

THIS asterisk is an operator... the "dereference operator". It is used quite a bit for things like smart pointers and iterators.

Same character, different placement, different meaning.

Mark Storer
  • 15,672
  • 3
  • 42
  • 80
  • It is not really accurate to say the asterisk qualifies the type. Grammatically, it qualifies the thing being declared. The fact that the thing being declared is a pointer is then deduced by reversing the grammatical construction. – Eric Postpischil Dec 23 '19 at 19:20
  • @EricPostpischil Would you say the same thing about `unsigned`? – 3Dave Dec 23 '19 at 19:23
  • Confusingly, my "The C++ Programming Language" (second edition, published in 1991) refers to the-asterisk-in-a-type-declaration as a **declaration operator**. Whee. – Mark Storer Dec 23 '19 at 19:25
  • The difference between `unsigned` and `*` can be seen when you declare multiple variables at once. Consider `unsigned int *a, b` – Lou Franco Dec 23 '19 at 19:27
  • That's hardly confusing at all. Yet another "Principle of Least Surprise" failure. – Mark Storer Dec 23 '19 at 19:28
  • page 94 Kernighan and Ritchie, C programming language states, the unary operator * is the "indirection" or "dereferencing" operator. When applied to a pointer it accesses the object that the pointer points to. – Frank Mancini Dec 23 '19 at 19:56
  • @3Dave: `unsigned` and `int` play the same role in `int *p` and `unsigned *p`. – Eric Postpischil Dec 23 '19 at 22:02
-1

You are declaring a pointer to an int. example of usage.

int x = 1;
int *p;

// you are assigning the address of the int to the pointer
p = &x;

printf( "int %i ptr %i\n", x, *p );
Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
  • The * notation accesses the object pointed to, the line p = &x, is assigning the address of the integer value to the pointer, so when accessing the value by *p, you can get the actual value that the pointer is pointing to. – Frank Mancini Dec 23 '19 at 20:03
-2

The comment here puts it so well, I decided to quote it as an answer to my own question (thanks to @bolov to linking!):

Don't think of int* as 2 pieces. It is one thing, it is the "type." (e.g., it would be as if they used an intp keyword for the int pointer type but the chosen syntax works for all types).

AlwaysLearning
  • 7,257
  • 4
  • 33
  • 68
  • 1
    Unfortunately, the comment is wrong, as can be proven by considering `int *p, a[3], x()`. This declares `p` to be a pointer to an `int`, `a` to be an array of 3 `int`, and `x` to be a function with no arguments that returns an `int`. But there is only one `int`, so it cannot be a single integral piece for all three of them. In fact, in the C++ grammar, `*` and `p` are parsed together, and `int` is separate. After that, in `int *p;`, the `int` is joined with `*p`. In `int *p, a[3], x();`, each item is parsed separately, then formed into a list `*p, a[3], x()`, and only then joined with `int`. – Eric Postpischil Dec 23 '19 at 22:07
  • @EricPostpischil The comment means that your example is equivalent to something like `intp p; int a[3]; int x()`. – AlwaysLearning Dec 24 '19 at 07:29
  • Showing the list was only used to illustrate the parsing. Separating the items into separate declarations does not change the C++ grammar. In the C++ grammar, specified in the Declarations ([dcl.dcl]) and Declarators ([dcl.decl]) clauses of the C++ standard, the type specifiers (`int`, `unsigned int`, and so on) are separate from the declarators (`*`, `*[]`, and so on). Saying they are one thing, the type, is not an accurate reflection of the C++ standard. – Eric Postpischil Dec 24 '19 at 12:34