char* p vs char *p

char* p vs char *p

By Mike Toms

Overload, 2(4):, February 1994


In the epilogue of issue 3 I asked if anyone knew why we could not have char* x, y; to mean both x and y were char pointers and char *x, y; to mean x is a char pointer and y is only a char.

Sean Corfield (UK ISO C++ representative) replies:

Mike,

Just glancing through issue 3 again and saw your comment in the epilogue about int * x, y; If you mean 'what is the technical reason' it's this:

A declaration is a sequence of specifiers followed by a comma-separated list of declarators. Specifiers are things like int, const, typedef etc.

Declarators include identifiers, but also include *, &, [], () etc.

Because whitespace is not significant in C+ + (or C), your declaration looks like this:

int          *x         ,        y              ;
specifiers   declarator ,        declarator     ;

Could we change this? Technically, yes, change the grammar so that pointer operators are part of the specifier-list:

int*          x          ,       y             ;
specifiers    declarator ,       declarator    ;

Unfortunately, C++ has to stay (fairly) compatible with C and that would break too much code.

As an aside, this example is precisely why I recommend that people always put declare each identifier in a separate declaration on a separate line:

int*    x;
int     y;

That's much clearer.

Regards,
Sean Corfield

By coincidence, Rick Stones (who is monitoring the comp.lang.C++ newsgroup for interesting threads) has just send me a thread on the same subject.

<Craig Cockburn> Is there any difference between the declaration

char  *x and  char*   x

<Joe Foster> Not to the compiler. I find char* x clearer, but this can trip you up.

Say you have the following definition:

char*   x,   y,    z () ;

It looks at first glance like y is a char* and z() returns char*, right?

Wrong. If you prefer char* x to char *x, make sure to declare or define everything separately, like so:

char* x; char* y; char* z();

<Gerhard Thallinger> From a compilers point of view there is no difference. Its only a question of style how you declare a pointer.

I would like to know what the reason is, that a majority of C++ programmers (as far as I can say that from looking at sources from public domain class libraries) use the notation 'char* x'?

Does anybody know why Bjarne Stroustrup is using this notation in the ARM ?

<Thaddeus L. Olczvk>

Since he occasionally read this group, he might actually tell us what he was smoking when he did this.

My best guess is that it makes prototyping a bit easier.

In

void  foo(char   *pc)   //  yes   I'm  PC   

... if you move this line from the .cc to .hh file to make the declaration, it is easier to accidentally delete the * this way. Of course if you pay attention.

<Michael Utech>

Syntactically? No.

I prefer 'char* x', simply because it looks better to me.

Several style guides encourage the use of 'char *x' because of reasons I forgot. It's a matter of taste.

<Reto J. Hermann>

I believe the reason why style guides encourage 'char *x' is for the cases where you have a list of variables to declare, i.e.,

char* x, y, z;    // might suggest all of x, y, z are of (char*)
               // in fact, this is equivalent to char* x, char y, char z
char *x, y, z;    // brings the actual meaning out a bit crisper

<Paul J Lucas>

Syntactically? Yes. One is space star, the other is star space. Semantically, there is no difference.

I prefer 'char* x', simply because it looks better to me.

To each, his own...but I don't have to read your code,

char* p, q; // char *p; char q; - not what it looks like!

God (otherwise known in this context as Dennis Ritchie) intended the * to go next to the variable name.

<Charles William Hubbard>

Yes, exactly right. In the book "Code Complete" the author actually encourages the use of the "char* x" format because the '*' changes the type (now a pointer to a char -- not a char) and he feels it should go with the type, not the variable. Normally this causes the problem you describe. However, the author also discourages declaring more than one variable per line. He says this provides room for a comment description of each variable. It also solves the problem you mention.

I'm not sure which of these points of view I favour. I prefer the "char* x" syntax over "char *x" and I also think a comment line for each variable is a nice thing (especially for globals or module variables).

However, there are many times when I'd rather declare multiple variables per line (i.e. "int i,j,k;" or "double minimum, maximum, mean;").

<Nigel Backhurst>

This can be very important, I have recently looked at incidents involving safety critical software. In three, the mistake had been made of presuming that in the declaration:

char* x, y, z;

y was a pointer to a character. There is from the safety point of view a strong argument for the view that multiple declarations on one line should not be allowed. They would say the above should be declared as:

char *x; char y; char z;

I feel that for most software this is going over the top, but if I was defining a style guide for safety critical software I would insist on it.

<Thomas M. Breuel>

It also has to do with what C/C++ type declarations actually are intended to express. Many people seem to think of them as "<type> <variable_name>" and get very confused. A better way of thinking of them is as "<type> <expression>". That is, you declare the type of the "expression" on the right:

char *x;

This means that the type of the expression "*x" is "char".

RE: safety critical software. - I agree.

<Robin Rowe>

If safety-critical software is the issue, then there is something wrong with your example. It should be one of these:

const char* const x; 
const char* x;
char* const x;

It is unlikely that the programmer actually needed a pointer that could be modified both by contents and location.

<Obi Thomas>

But God++ (aka Bjarne Stroustrup) favours char* p over char *p.

<Jerzy Sobczyk>

RE: Gerhard Thallinger

Making prototypes I never delete variable names (unless forced by stupid compilers).

According to the grammar it is not necessary. (Only semicolon on the end is needed).

What's more - it helps to locate the point when you make an error in function call like invalid type of a parameter -then compiler can use the name of a parameter in question in error message pointing exactly what's wrong.

<Robert Schmidt>

RE: Obi Thomas

And if he does, that's his problem. I and many others feel most comfortable seeing declarations like:

char *s1, s2[], s3;       // as I like it

instead of

char* s1, s2[], s3;       // as I do not like it

If you (any of you) disagree with this, that's fine with me, as long as I am not forced to clean up your code.

Anyway, it's just a matter of replacing for "char* " with "char *" with some standard utility. As Lucas points out above, "char *" was the original intent, and even Stroustrup doesn't have the power to push his personal style onto everybody else.

Just my 2 cents, nuthin more.

<Paul J Lucas>

This is one of the few places where I quibble with Bjarne.

Dennis got it right and it is eloquently explained in the C Programming Language:

int *p;

The *p is what is an int.

I think Bjarne unnecessarily continues to confuse new C++ programmers. The fact that this question has been posted a number of times is proof. I can only hope that he corrects this in his 3rd edition. (And goes back to calling arrays "vectors" like he did in his first edition...but that's a different quibble.)

No offence, Bjarne.

<Tony Coates>

I must say that while I prefer to type

int* p;

myself, it's too easy to end up writing

int* p,q;

which gives you a pointer and an int instead of what you probably wanted.

At least if you write

int *p;

then you will probably write

int *p,*q;

to give you the two pointers you probably wanted.

Otherwise, I would do

typedef int *pint; pint p;

which at least circumvents the entire problem, as the risk of cluttering the name-space up a bit.

Anyway, just my thoughts.

<david.finch>

The C++ spec should be changed so that

char*  a, b, c: 

is

char*  a; 
char* b;
char* c;

and

char   *a, b, c;

is the old way.

I think you are wrong new C and C++ programmers are more confused why

char   *a, b, c;

is not

char*  a; 
char* b;
char*  c;

I know that everyone I have known that has learn C has found this difficult including myself (6 years of C now). I think that it is such a pain that I convert all code to have declaration in a line so people can not be confused in anyway of its type.

P.S.

thanks to the poster that informed us that it should be read

type    expresion

but this is not what the beginning programmer expects a language to have as its declarations statements.

<JoeFoster>

Keep in mind that God++ also doesn't often define or declare two or more variables, arrays, or functions in the same statement.

It's very easy to get the wrong idea of y's type, for example:

char* x, y();

Remember that we are mere mortals and that mortals have limits, unlike Gods and God++'s.:-)

<Bjarne Stroustrup>

Naturally "*p is an int," and also "the type of p is int*."

Which kind of statement do you focus on?

int* p; vs int *p;

is not a question of right and wrong, but one of style and emphasis.

C - especially early C - emphasised expressions; declarations were often considered little more than a necessary evil. C++, on the other hand, has a heavy emphasis on types.

RE: Bjarne unnecessarily continues to confuse new C++ programmers.

Actually, I consider the C declarator syntax an experiment that failed.

Having both prefix and postfix operators in declarations is a bad idea that has caused and will continue to cause endless confusion.

This particular source of confusion predates even Dennis. The best we can do is to try to minimise confusion through style.

The critical confusion comes only when people insist on declaring several variables with a single declaration:

int* p, a;

and in particularly when they fail to initialise those variables. I have consistently recommended against both practices. To contrast:

int* p = &i; 
int a = 7;

is not likely to confuse anybody, and the compiler will catch many mistakes:

int* p = 7; // error: int* initialized with int 
int a = &i; // error: int initialized with int*

RE: The fact that this question has been posted a number of times is proof.

No. Whenever something can be done in two ways someone will be confused.

Stick to one pointer per declaration and to initialized variables and the source of confusion disappears.

RE: I can only hope that he corrects this in his 3rd edition.

There in no 3rd edition on its way, and none is needed so far.

Anyway, I don't think you should hold your breath for a style change anyway. I prefer the style I use, I think I have good reasons for my preference, I encourage people to consider that style, and people who have different preferences are free to indulge them.

RE: No offence, Bjarne.

I'm sure none was meant and none was taken.






Your Privacy

By clicking "Accept Non-Essential Cookies" you agree ACCU can store non-essential cookies on your device and disclose information in accordance with our Privacy Policy and Cookie Policy.

Current Setting: Non-Essential Cookies REJECTED


By clicking "Include Third Party Content" you agree ACCU can forward your IP address to third-party sites (such as YouTube) to enhance the information presented on this site, and that third-party sites may store cookies on your device.

Current Setting: Third Party Content EXCLUDED



Settings can be changed at any time from the Cookie Policy page.