Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ style: Stroustrup' s placement of pointer asterisks

Does anyone know why Stroustrup's style is the placement of pointers as follows? Specifically, what Stroustrup has provided for guidance about this matter?

int* p; 

vs

int *p; 

because declaring multiple variables would require the asterisk next to each variable name. Which would result in:

int* p, *x; 

vs

int *p, *x; 

In K&R C book, they explain that the asterisk/pointer is used as a mnemonic to aid in understanding. I find it odd that the pointer/asterisk is tied to the type, vs the variable as the second of each example shows. Interested if there is some background to why the first style is chosen.

Hoping for some quote from Stroustrup in the reasoning for this.

I'm adding in K&R C 2nd Edition grammar Page 235 where the asterisk (pointer) is tied to the declarator, which is an identifier.

K&R p235 2nd Ed

ANSWER In this article from Stroustrup on coding style. He explains that both are valid and it depends on programmer preference.

I disagree that this is an opinion based question. Stroustrup's article clearly answers the question without opinion.

like image 229
notaorb Avatar asked May 25 '20 01:05

notaorb


People also ask

Where should the asterisk go in a pointer?

When declaring a pointer type, place the asterisk next to the type name. Although you generally should not declare multiple variables on a single line, if you do, the asterisk has to be included with each variable.

What does * and &indicate in pointer?

The fundamental rules of pointer operators are: The * operator turns a value of type pointer to T into a variable of type T . The & operator turns a variable of type T into a value of type pointer to T .

What does the * mean in pointers?

A pointer is a variable that stores the memory address of another variable as its value. A pointer variable points to a data type (like int ) of the same type, and is created with the * operator.

What is * in front of variable in C?

In computer programming, a dereference operator, also known as an indirection operator, operates on a pointer variable. It returns the location value, or l-value in memory pointed to by the variable's value. In the C programming language, the deference operator is denoted with an asterisk (*).

When do you use a pointer in C++?

If passing ``not an object'' (e.g. a null pointer) is acceptable, using a pointer makes sense. My personal style is to use a pointer when I want to modify an object because in some contexts that makes it easier to spot that a modification is possible.

Where do you put an asterisk at the bottom of a page?

Whenever an asterisk is placed within a text, a corresponding asterisk is placed at the bottom of the page, within the footer area, directly below the printed textual material. This footnote asterisk should contain some explanation, limitation, or elucidation of the text.

Why can't C compiler catch misuses of pointer types?

Maybe x and y are unrelated pointer types. Because the C-style cast (T) can be used to express many logically different operations, the compiler has only the barest chance to catch misuses. For the same reason, a programmer may not know exactly what a cast does.

When do you use a pointer to modify an object?

My personal style is to use a pointer when I want to modify an object because in some contexts that makes it easier to spot that a modification is possible. Note also that a call of a member function is essentially a call-by-reference on the object, so we often use member functions when we want to modify the value/state of an object.


Video Answer


2 Answers

C++ emphasis heavily on types and when it comes to pointers declaration, to avoid any sort of confusion, Bjarne suggested - Stick to one pointer per declaration.

From Bjarne Stroustrup's C++ Style and Technique FAQ [emphasis added]:

Is int* p; right or is int *p; right?

Both are "right" in the sense that both are valid C and C++ and both have exactly the same meaning. As far as the language definitions and the compilers are concerned we could just as well say int*p; or int * p;

The choice between int* p; and int *p; is not about right and wrong, but about style and emphasis. C emphasized expressions; declarations were often considered little more than a necessary evil. C++, on the other hand, has a heavy emphasis on types.

A typical C programmer writes int *p; and explains it *p is what is the int emphasizing syntax, and may point to the C (and C++) declaration grammar to argue for the correctness of the style. Indeed, the * binds to the name p in the grammar.

A typical C++ programmer writes int* p; and explains it p is a pointer to an int emphasizing type. Indeed the type of p is int*. I clearly prefer that emphasis and see it as important for using the more advanced parts of C++ well.

The critical confusion comes (only) when people try to declare several pointers with a single declaration:

int* p, p1; // probable error: p1 is not an int*

Placing the * closer to the name does not make this kind of error significantly less likely.

int *p, p1; // probable error?

Declaring one name per declaration minimizes the problem - in particular when we initialize the variables. People are far less likely to write:

int* p = &i; int p1 = p; // error: int initialized by int*

And if they do, the compiler will complain.
Whenever something can be done in two ways, someone will be confused. Whenever something is a matter of taste, discussions can drag on forever. Stick to one pointer per declaration and always initialize variables and the source of confusion disappears.

See The Design and Evolution of C++ for a longer discussion of the C declaration syntax.

like image 107
H.S. Avatar answered Oct 08 '22 14:10

H.S.


I cannot speak for Bjarne, but tying the asterisk (and ampersand in case of reference) to the type makes sense because being a pointer is semantically part of the type of the variable. The name of the variable is p and its type is int*. The name is not *p and the type is not int.

It is nearly always possible to avoid multiple variable declarations in a single declaration, so that is not an issue.

In my opinion, this approach is clearer, especially in case of return types:

T* function(Args...);  T *function(Args...); 
like image 45
eerorika Avatar answered Oct 08 '22 14:10

eerorika