Jump to content


Why int *foo instead of int* foo?


41 replies to this topic

#1 poita

    Senior Member

  • Members
  • PipPipPipPip
  • 322 posts

Posted 04 June 2007 - 02:54 PM

This has always bugged me: why is it common practice to put the pointer symbol (*) beside the identifier instead of the type? I know that both ways are perfectly legal but why is the less logical one (at least for me) the most common?

It seems logical to me that a declaration of this sort should go:

<Type><Space><Identifier>;

The * is part of the type, not part of the name.

When you say int *foo you are creating a variable "foo" that is of type pointer-to-int or as I would see it "int*".

Is it just become one of those habit things that have continued for consistency's sake or is there an actual reason that the * goes with the identifier instead of the type?

#2 dave_

    Senior Member

  • Members
  • PipPipPipPip
  • 584 posts

Posted 04 June 2007 - 03:03 PM

Backwards compatibility... I think. I was at a conference where even stroustrup admitted it was a mistake

#3 tbp

    Valued Member

  • Members
  • PipPipPip
  • 135 posts

Posted 04 June 2007 - 03:14 PM

Because

int*

	p,

	q;



#4 poita

    Senior Member

  • Members
  • PipPipPipPip
  • 322 posts

Posted 04 June 2007 - 03:23 PM

tbp said:

Because

int*

	p,

	q;


Ahh, I see.

IMO int* p,q should create 2 pointers, not a pointer and an int. That seems more logical to me.

#5 .oisyn

    DevMaster Staff

  • Moderators
  • 1842 posts

Posted 04 June 2007 - 04:26 PM

I usually type
int * foo;
:P
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#6 Nick

    Senior Member

  • Members
  • PipPipPipPip
  • 1227 posts
  • LocationOttawa, Ontario, Canada

Posted 04 June 2007 - 08:12 PM

poita said:

The * is part of the type, not part of the name.
It depends how you look at it. When I write "int *foo" what I really want is the integer. The fact that this integer is accessed by a pointer is just a detail. As a matter of fact, writing "int foo" creates a pointer too. The integer will be created on the stack and to access it the stack pointer and the offset is needed (whether or not the compiler decides to keep the variable in a register is just another detail).

So you could regard the explicit indirection as more closely related to the way the variable name is used, than the type itself. int is the type, and *foo is how we access it.

Of course, these arguments are just 'excuses' to explain the somewhat odd semantics of what tbp illustrated... But it works for me! :lol:

#7 Nick

    Senior Member

  • Members
  • PipPipPipPip
  • 1227 posts
  • LocationOttawa, Ontario, Canada

Posted 04 June 2007 - 08:14 PM

.oisyn said:

I usually type
int * foo;
^_^
What's the result of multiplying int and foo? ;) That gets even more confusing with typedefs and classes with overloaded operators...

#8 .oisyn

    DevMaster Staff

  • Moderators
  • 1842 posts

Posted 04 June 2007 - 08:25 PM

The person that overloads operator*() that has side-effects rather than return a new value that can be assigned to something should be shot on sight :P
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#9 dave_

    Senior Member

  • Members
  • PipPipPipPip
  • 584 posts

Posted 04 June 2007 - 08:33 PM

typedef char* foo;
const foo x;

typedef const char bar;
bar* y;
to add another confusion: is x the same type as y? ;)

just another example of confusing C++ syntax, it makes a lot more sense if you change where you place your const.
typedef char* foo;
foo const x;

typedef char const bar;
bar* y;


#10 SamuraiCrow

    Senior Member

  • Members
  • PipPipPipPip
  • 459 posts

Posted 04 June 2007 - 09:46 PM

C and C++ are full of confusing syntax. I can see why some people would rather shell out the bucks for Blitz Basic than use Code::Blocks and MinGW for free.

#11 Nautilus

    Senior Member

  • Members
  • PipPipPipPip
  • 353 posts

Posted 05 June 2007 - 02:24 PM

poita said:

Ahh, I see.

IMO int* p,q should create 2 pointers, not a pointer and an int. That seems more logical to me.
I agree with you.
This demonstrates that the compiler parses the star (*) as part of the identifier, and not as part of the type.
The fact that no syntax error is raised when compiling int* Foo; is a bonus, although welcome.

Yet, I'd like to see modern compilers featuring the option to raise a syntax error (at least a warning) when [type]* [identifier], or the opposite, is found.
It would help to enforce the same coding convention throughout a team project.

Ciao ciao : )
-Nautilus

(readin' this? you ought to get out more)


#12 .oisyn

    DevMaster Staff

  • Moderators
  • 1842 posts

Posted 05 June 2007 - 02:39 PM

dave_ said:

typedef char* foo;
const foo x;

typedef const char bar;
bar* y;
to add another confusion: is x the same type as y? :P

const bar* z;
and what is z? :)
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#13 flux00

    Valued Member

  • Members
  • PipPipPip
  • 108 posts

Posted 08 June 2007 - 02:29 AM

Is it possible in c++ to have a array of const ints, and differentiate that from a const array of ints?

#14 Jare

    Valued Member

  • Members
  • PipPipPip
  • 247 posts

Posted 08 June 2007 - 07:51 AM

What's the difference you are looking for? The array contains the ints and nothing else, so if the ints are const, the whole array should be const (and viceversa).

#15 .oisyn

    DevMaster Staff

  • Moderators
  • 1842 posts

Posted 08 June 2007 - 09:43 AM

Indeed. A pointer can have two "types of const" (the pointer itself can be const, and the object pointed to can be const), because you are allowed to alter both the pointer itself and the data pointed to.

You can't alter an array - only it's elements. So there's no such thing as a const array of non-const elements or vice versa, that doens't make any sense. The same with references. You can't alter references, so const references don't exist.
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#16 flux00

    Valued Member

  • Members
  • PipPipPip
  • 108 posts

Posted 08 June 2007 - 08:59 PM

hmm, if I wanted to create an array of abstract classes, would I just make an array of references to the abstract class?


class A

{

	public:

		virtual int get() = 0;

};

class B

{

	public:

		int get()

		{

			return 5;

		}

};

class C

{

	public:

		int get()

		{

			return 8;

		}

};

int main()

{

	int len = 10;

	(A&)* arr = new (A&)[len];	//?

}



#17 .oisyn

    DevMaster Staff

  • Moderators
  • 1842 posts

Posted 08 June 2007 - 09:58 PM

You can't create arrays of references - you'll need an array of pointers.
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#18 anubis

    Senior Member

  • Members
  • PipPipPipPip
  • 2225 posts

Posted 10 June 2007 - 09:25 AM

Most of these oddities probably stem from pre ansi function parameter lists. When function parameters where declared outside of the actual function head like this :


void foo(a, b, c)

int a, b;

float c;

{

   ...

}


the logic must have been that the function gets n parameters of type int. Wheather the variables are pointers or arrays then was seen as additional information to the type, that goes with the variable name. But that's probably a bad explanation for something purely concidental as well :)
If Prolog is the answer, what is the question ?

#19 t0rakka

    New Member

  • Members
  • Pip
  • 9 posts

Posted 25 June 2007 - 06:35 PM

It's a matter of preference, I prefer to think this way:

int* p; // pointer (to int) named p

I don't think like this:

int *p; // int (pointer to named p)

It's simple as that. I never declare more than one variable per line, so I get around the usual trap of:

int* a, b;

I never write..

int i, j;

.. either. I have a habit of initializing the variables, if possible, at declaration-- this comes from serious trauma at childhood: I learned assembly (z80) pretty much as the first programming language.

Second, when I (have to, like, at work) write C, I _try_ to initialize at declaration because I don't want to separate variables from their initialization by dozen or more lines of code. If there is that much code between the variable and assigning to one, then the function probably is too large anyway (or maybe not).

There is only one enemy (when writing C) to this scheme; asserts. Often you want to assert function arguments, well, duh?

void example(foo* bar)
{
assert( bar .. blablablablaaa );
int size = xxxComputeFapFactor(bar);

^ Anyone care to notice the error in above example? Oh yes, the assert before declaration. Question arises? Why not leave the assert to the xxxComputeFapFactor() then? A: becuase this is a *****ing example!

:) :)

#20 Reedbeta

    DevMaster Staff

  • Administrators
  • 5309 posts
  • LocationSanta Clara, CA

Posted 25 June 2007 - 08:00 PM

In C99 you can do the declaration after the assert just fine.
reedbeta.com - developer blog, OpenGL demos, and other projects





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users