tags:

views:

257

answers:

6

I'm relatively new to C++ (about one year of experience, on and off). I'm curious about what led to the decision of type * name as the syntax for defining pointers. It seems to me that the syntax should be type & name as the & symbol is used everywhere else in code to refer to the variable's memory address. So, to use the traditional example of int pointers:

int a = 1;
int * b = &a;

would become

int a = 1;
int & b = &a

I'm sure there's some reason for this that I'm just not seeing, and I'd love to hear some input from C++ veterans.

Thanks, -S

+1  A: 

Your second example is not valid C code, only C++ code. The difference is that one is a pointer, whereas the other is a reference.

On the right-hand side the '&' always means address-of. In a definition it indicates that the variable is a reference.

On the right-hand side the '*' always means value-at-address. In a definition it indicates that the variable is a pointer.

References and pointers are similar, but not the same. This article addresses the differences.

Christopher
I don't think the second block is *supposed* to be legal code - it's a hypothetical example.
Andrew Medico
Thank you, the article (and the disambiguation of references and pointers) was helpful.
spencewah
The second example is valid neither in C nor C++. You don't use the address operator to bind a reference to a value.
Luc Touraille
+5  A: 

It is C who defined this not C++ :)

again these operators are not only used for memory operations.

Why this syntax is not adopted in C++, for compatibility with C, don't forget also C++ has a use for & ;)

int & b = a;

the above line, means a reference variable pointing to another regular variable 'int' in this case. The difference between a reference and pointer roughly is that references are initialized only, and you can not change where they point, and finally they are always dereferenced automatically.

int x = 5, y = 10;
int& r = x;

int sum = r + y; // you do not need to say '*r' automatically dereferenced.

r = y; // WRONG, 'r' can only have one thing pointing at during its life, only at its infancy ;)
AraK
Thank you, I was making some incorrect assumptions about references and pointers (mainly that they are one in the same, when they are not).
spencewah
+1  A: 

Instead of reading int* b as "b is a pointer to int", read it as int *b: "*b is an int". Then, you have & as an anti-*: *b is an int. The address of *b is &*b, or just b.

Tordek
A: 

I think the answer may well be "because that's the way K&R did it."

Downvoting fools. Explain why I'm wrong.

K&R are the ones who decided what the C syntax for declaring pointers was.

It's not int & x; instead of int * x; because that's the way the language was defined by the guys who made it up -- K&R.

smcameron
+2  A: 

If you are a visual thinker, it may help to imagine the asterisk as a black hole leading to the data value. Hence, it is a pointer.

The ampersand is the opposite end of the hole, think of it as an unraveled asterisk or a spaceship wobbling about in an erratic course as the pilot gets over the transition coming out of the black hole.

I remember being very confused by C++ overloading the meaning of the ampersand, to give us references. In their desperate attempt to avoid using any more characters, which was justified by the international audience using C and known issues with keyboard limitations, they added a major source of confusion.

One thing that may help in C++ is to think of references as pre-prepared dereferenced pointers. Rather than using &someVariable when you pass in an argument, you've already used the trailing ampersand when you defined someVariable. Then again, that might just confuse you further!

One of my pet hates, which I was unhappy to see promulgated in Apple's Objective-C samples, is the layout style int *someIntPointer instead of int* someIntPointer

IMHO, keeping the asterisk with the variable is an old-fashioned C approach emphasizing the mechanics of how you define the variable, over its data type.

The data type of someIntPointer is literally a pointer to an integer and the declaration should reflect that. This does lead to the requirement that you declare one variable per line, to avoid subtle bugs such as:

int* a, b;  // b is a straight int, was that our intention?

int  *a, *b;  // old-style C declaring two pointers

int* a;
int* b;  // b is another pointer to an int

Whilst people argue that the ability to declare mixed pointers and values on the same line, intentionally, is a powerful feature, I've seen it lead to subtle bugs and confusion.

Andy Dent
+1, great comment on declaration syntax.
Paul Morie
+2  A: 

I think that Dennis Ritchie answered this in The Development of the C Language:

For each object of such a composed type, there was already a way to mention the underlying object: index the array, call the function, use the indirection operator on the pointer. Analogical reasoning led to a declaration syntax for names mirroring that of the expression syntax in which the names typically appear. Thus,

int i, *pi, **ppi;

declare an integer, a pointer to an integer, a pointer to a pointer to an integer. The syntax of these declarations reflects the observation that i, *pi, and **ppi all yield an int type when used in an expression. Similarly,

int f(), *f(), (*f)();

declare a function returning an integer, a function returning a pointer to an integer, a pointer to a function returning an integer;

int *api[10], (*pai)[10];

declare an array of pointers to integers, and a pointer to an array of integers. In all these cases the declaration of a variable resembles its usage in an expression whose type is the one named at the head of the declaration.

So we use type * var to declare a pointer because this allows the declaration to mirror the usage (dereferencing) of the pointer.

In this article, Ritchie also recounts that in "NB", an extended version of the "B" programming language, he used int pointer[] to declare a pointer to an int, as opposed to int array[10] to declare an array of ints.

bk1e
Indeed. And doing int i, it would be illegal, because
Johannes Schaub - litb