34

I'm learning C++ at the moment, and I'm coming across a lot of null-terminated strings. This has got me thinking, what makes more sense when declaring pointers:

char* string

or

char *string

? To me, the char* format makes more sense, because the type of "string" is a pointer to a char, rather than a char. However, I generally see the latter format. This applies to references as well, obviously.

Could someone tell me if there is a logical reason for the latter format?

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Skilldrick
  • 69,215
  • 34
  • 177
  • 229
  • std::wstring, of course. – Hans Passant Feb 17 '09 at 20:37
  • The first format makes more sense. You're declaring a variable named 'string' that has a type of `char*`, not a variable named '*string' that has a type of `char`. People intuitively parse code along whitespace boundaries, so it's reasonable to format code so that it reads meaningfully when parsed that way. Of course, the answers below explain why sometimes the counterintuitive convention is used. – aroth May 07 '13 at 03:13

13 Answers13

71

In the following declaration:

char* string1, string2;

string1 is a character pointer, but string2 is a single character only. For this reason, the declaration is usually formatted like:

char *string1, string2;

which makes it slightly clearer that the * applies to string1 but not string2. Good practice is to avoid declaring multiple variables in one declaration, especially if some of them are pointers.

Hosam Aly
  • 41,555
  • 36
  • 141
  • 182
Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • 5
    IMHO this should not be considered as THE good answer. Considering that: - We are talking about C++ - The type is char* - The variable that you'll pass around is "string", and rarely "*string". - A variable must be declared as late as possible, so by definition not on the same line than another one. - Bjarne says "A typical C++ programmer writes int* p... I clearly prefer that emphasis and see it as important for using the more advanced parts of C++ well. - const char* const string Then char* string makes definitely more sense. I even prefer char * string, for clarity. – Jem May 06 '09 at 19:49
  • 2
    I don't find it in any occasion sensible to declare variables of different kind in the same line. – Chiel Jan 27 '15 at 09:27
  • 9
    This is such nonsense. Why does everybody obsess over this edge case?! There are far more important factors to consider when deciding how to align your asterisks. – Lightness Races in Orbit Feb 12 '15 at 22:16
  • 1
    It's a *bad* idea to declare different kind of variables on the same line, but it still applies that **a)** most beginners / non C++ programmers would interpret `char* string1, string2;` as two pointers, and **b)** the asterisk *isn't* a modifier on the type specifier itself, but a modifier on the name. Imagine it as XML: You have a declaration element with type attribute, and one or more child elements with variable names. Now *why* would you add the pointer-modifier (*) as an attribute to the type element when it applies to its first child element only? That said `char*` is more readable. :( – AnorZaken Jul 29 '16 at 17:24
37

Bjarne Stroustrup has something to say about this:

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*
System.Cats.Lol
  • 1,620
  • 1
  • 26
  • 47
smo
  • 913
  • 7
  • 11
  • 1
    Brilliant! Stroustrup agrees with me! Thanks. – Skilldrick Feb 17 '09 at 20:06
  • This is how I've always felt about it. – Nick Presta Feb 17 '09 at 22:41
  • 2
    If you scroll through Stroustup's FAQ, it's interesting to see which pointer style he actually uses in his own code. – otto Jan 31 '12 at 17:05
  • [Real world example!](http://stackoverflow.com/a/13618287/1836314) – matpop Jan 16 '15 at 09:40
  • 2
    The C++ Core Guidelines state the operator should be adjacent to the type: https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#nl18-use-c-style-declarator-layout – phoenix Jan 01 '16 at 21:46
  • 6
    @otto Well, if you've actually read his post, you'd see he's using the very style he said he prefers. This answer is somewhat misleading because it's hiding the actual context, and the important point: "*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** [...].* – Tomáš Zato Jan 11 '16 at 09:59
  • @TomášZato Yup. I agree with you. Sorry, my previous comment was indirect. What I wanted to communicate, this answer pulls a particular excerpt from the FAQ explaining the main justification behind `int *p;` that I often hear from its advocates. However, I thought it was interesting to see that Stroustrup himself actually uses the other style `int* p;` (and as you've pointed out, he explicitly states he prefers it). – otto Jan 11 '16 at 17:07
  • 4
    *Read the full context!* This is taken completely incorrectly out of context to make the *opposite* point of what Stroustrup is saying! – Apollys supports Monica May 30 '19 at 00:54
18

Technically, it makes sense to write

char *f

Because *f is the declarator in that, while the char is the declaration specifier which specifies a basic type of all the declarators. The declarators contain operators like (), [] and & which can be thought of modifying the base type, and the actual identifier.

I use the above form of putting * to the identifier because it emphasizes that *f actually is the declarator, while char is the basic type.

To a degree, one can think of the modifiers in a declarator to make the type in the declaration specifier when the operators are applied to the identifier. But it does not always work:

int a, *b, &c = a, d(), e[1], C::*f;

Note how all of a, *b, d() and e[1] statically resolve to an int - apart from &c and C::* which declare a reference (thus it needs to be initialized) and a pointer to a class member respectively.

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
  • This comment may be controversial. Pace Stroustrup, but not Ritchie who wrote the main lines of the grammar he extended, if one places a declarator operator like * right after a declaration specifier sequence like const foo as in const foo* bar it is easy to misread it as a constant (pointer to a foo) rather than a pointer to a (constant foo). To get clear on the complexities of declaration syntax it's useful to read the grammar appendix to K&R or Stroustrup's The C++ Programming Language. – egyik Aug 27 '16 at 07:19
11

What no one mentioned yet is that the following

char *string

can also be read as declaring the type of the expression *string (read: the indirection operator applied to the pointer string) as char. From this point of view, the notation is perfectly reasonable.

That being said, I use

char * string

myself ;)

Christoph
  • 164,997
  • 36
  • 182
  • 240
  • 1
    "That being said, I use char * string" - Me too, I started converging on this format after considering both the 'char* ' and 'char *' formats and wasn't happy with either of them ... – stefanB May 13 '09 at 02:38
  • +1, useful interpretation of otherwise confusing syntax! – anton.burger Jul 30 '10 at 20:32
5

In C++ it makes sense to put the * at the type identifier like char*, as it is part of the type itself.

But if you define multiple variables in the same statement this gets ambiguous and misleading.

char* foo, bar;

While foo has the type char* now, bar has the type char. Therefore many people prefer

char *foo, bar;

to make this clear.

raimue
  • 4,322
  • 1
  • 21
  • 31
  • This situation is rectified by simply knowing the language. And if a reader of code is mislead or confused by a writer of working code writing `char* foo, bar;`, that's on the reader for not knowing the language well enough. – Pulseczar Jul 13 '20 at 20:23
  • "as it is part of the type itself." Doesn't the second example behave the same way in both C++ vs C? – endolith Jul 08 '22 at 20:57
5

(std::string is better than char* for most uses.)

I always put the * with the type, as in char* because, as Stroustrup noted, this emphasizes the type.

And I never declare variables together on one line to avoid the common gotcha discussed in the responses here;

char* p, q;  // oops, probably not what was meant
// this is mandated by our style guide:
char* p;
char* q;
nhed
  • 5,774
  • 3
  • 30
  • 44
Brian Neal
  • 31,821
  • 7
  • 55
  • 59
3

given that you can make multiple declarations on a single line it makes more sense to me that it belongs to the variable rather than the type, e.g.

char *pString, arrString[20];
Simon
  • 78,655
  • 25
  • 88
  • 118
3

In most cases, std::string str is much preferable to a char *.

That being said, I usually do something like DataType * ptr, to make the * stand out better. Or, much more often, std::tr1::smart_ptr<DataType> ptr, or maybe an auto_ptr.

Very simply, raw pointers are dangerous to use in quite a few ways, and if I'm going to use one I want it to stand out.

David Thornley
  • 56,304
  • 9
  • 91
  • 158
3

I really like the "char* foo" idiom, because it puts all the information about the variable's type in one place. "char *foo" can be quite confusing if the "*foo" part is tabbed halfway across the screen!

On the other hand, I do agree with other posters that it's confusing when declaring multiple variables on one line. I try not to mix types when declaring multiple variables on one line, and char and char* are separate types in my mind, so that particular situation isn't one that would likely occur in my code.

MattK
  • 10,195
  • 1
  • 32
  • 41
  • 2
    The problem is that the C type system doesn't work that way, instead it puts the declared variable or type in the middle. Just try to declare an array or a pointer to a function. – starblue Feb 17 '09 at 20:16
  • Yeah, that's true--my philosophy isn't applicable everywhere in C/C++, unfortunately. But I do like to declare pointers and references that way, for clarity. – MattK Feb 17 '09 at 20:48
3

My answer: neither, you should use:

char * string;

Consider, if Dennis Ritchie (designer of the C language) instead of using the '*' character had used a keyword 'ptr', we would all have to be saying:

char ptr string;

and not having these discussions.

It is also, IMHO, more readable.

Brian Neal
  • 31,821
  • 7
  • 55
  • 59
2

Personally I never declare multiple variables on one line.

Because of that and the fact that I really find patterns nice, I find this simple pattern appealing:

type varname

This means I almost always say int[] iArray or int* piArray (or whatever the hungarian notation would be, I haven't used C++ in a decade).

This also means that I never use int iArray[], since the fact that it's an array is part of the type, not the variable name.

Thinking this way has helped me simplify definitions a few times as well.

Just offering another POV

Bill K
  • 62,186
  • 18
  • 105
  • 157
1

I too think the char* foo makes more sense when declaring a single variable.

The only time I use the other format is when declaring multiple variables on a single line such as:

char *foo, bar;

TWA
  • 12,756
  • 13
  • 56
  • 92
1

The first suggestion (of char* var) would be fine as long as you only declared a single variable per line, but personally, I prefer the "char *var;" and a single variable per line - it may make the function longer in line count, but is very clear.

Finally, C++ should be using "string var", but we always end up either inheriting code with "char *" or having to connect to non-C++ libraries.

James Fisher
  • 292
  • 1
  • 6