Archived

This topic is now archived and is closed to further replies.

amish1234

pointers instead of reference: bad programming?

Recommended Posts

I''ve often seen code like this:

void Function(int* a)
{
   *a=5;
}

....
void main()
{
  int myint;
  Function(&myint);
}
The reason Function''s parameter is of type int* is so that the variable you pass to it will be equal to 5 after the function is called. But isn''t this what a reference is for? It should be like this:

void Function(int &a)
{
   a=5;
}

....
void main()
{
  int myint;
  Function(myint);
}
The first version might lead other people to think that I want you to pass an int*, when really I just want the int you pass to be equal to 5 even after the function call. Is there any reason I would want to do this with a pointer instead of a reference? If not, is this "bad" programming? ___________________________________________________________ Proceeding on a brutal rampage is the obvious choice. Where to find the intensity (Updated Jan 23, 2004)

Share this post


Link to post
Share on other sites
the first method you showed was the C way. they did not have reference variables. so you had to pass everything as a pointer.

the other way is the C++ way and they had reference variables

ie. int number;
int &number1 = number;

in any case, they are both correct and one is no more wrong than the other.

Share this post


Link to post
Share on other sites
I still prefer pointers... I find references leave things a little ambiguous. Passing a const pointer (not a pointer to a const) achieves the same thing and you aren''t left with that confusion.

Share this post


Link to post
Share on other sites
Passing as a reference is safer. There's also the const-ref. The only time I use pointers directly in parameters now is if I have an array.

edit: not only that, the syntax is cleaner too.

[edited by - Odoacer on January 25, 2004 8:30:46 PM]

Share this post


Link to post
Share on other sites
I''ve just made the transition from C to C++ myself, and I''m still a bit confused about when I should use references vs. pointers. I prefer not having to throw a & on what I''m passing, but if that variable changes in the function, I like the &. (I find & is a good warning... be careful, this function might change that variable). Ask me in another 6 months.

Share this post


Link to post
Share on other sites
I know some (quite a few actually) people who prefer to use a pointer if you are going to modify the variable, because it forces you to take the address of the variable, so it looks different when you call the function. For instance:

// This would tell them that the function does not modify
// the variable.
SomeFunction(var);

// This would tell them that the function DOES modify
// the variable.
SomeFunction(&var);

It makes sense. If you''re trying to debug something, and you just see: SomeFunction(var), and you used a reference, then you may forget that SomeFunction() modifies var. It''s not a big deal though.

I use a reference unless there is some reason to use a pointer, such as if I''m doing some pointer arithmetic, or bitwise operations on pointers

Share this post


Link to post
Share on other sites
quote:
Original post by Russell
// This would tell them that the function does not modify
// the variable.
SomeFunction(var);

// This would tell them that the function DOES modify
// the variable.
SomeFunction(&var);



This is almost as bad as using Hungarian Notation for naming
variables.

One of the main argument against HN is that modern IDE provides
mouse-over tool-tip showing the type of a variable.

The same functionality works to show the parameters of
a function (just move the mouse cursor over the name of
a function in VS.NET, for example).



Kami no Itte ga ore ni zettai naru!

Share this post


Link to post
Share on other sites
I try to avoid writing functions that manipulate parameters like that.

But if I''m in a jam I go for the pointer since it''s much more obvious what''s going to happen. I try to never pass a non-const reference, unless its a return value maybe.

Image loads when I''m online since I''m too lazy to find a permanent host.The following statement is true. The previous statement is false.
Shameless promotion:
FreePop: The GPL Populous II clone.

Share this post


Link to post
Share on other sites
quote:
Original post by tangentz
One of the main argument against HN is that modern IDE provides
mouse-over tool-tip showing the type of a variable.



That''s true, but the REAL problem with HN is that it produces ugly nausiating source code for no real benefit. The coder should have a good idea what type signature a function ought to be. The problem is that if the programmer isn''t sure what type a function accepts and gets it wrong it will not compile (unless the types can be converted, but that should be a trivial case), but if the programmer doesn''t realise that a function he uses modifies an argument given it will compile, and could produce buggy code. This is why I think this sort of pointer notation, which is much cleaner than HN garbage, is more important than HN and is appropriate in this case.

Image loads when I''m online since I''m too lazy to find a permanent host.The following statement is true. The previous statement is false.
Shameless promotion:
FreePop: The GPL Populous II clone.

Share this post


Link to post
Share on other sites
I tend to like pointer usage personally, but that''s mostly because A) I''m an old-school C freak, and B) I, as a programmer, like to know when I''m passing a pointer into a function as opposed to a copy of the object/data/etc... It lets me know if that thing has a chance of being modified.

Of course, one could note that with good commenting, you''d already know that about any given function that you use... so it''s a toss up.

Share this post


Link to post
Share on other sites
quote:
Original post by Doc
I try to avoid writing functions that manipulate parameters like that.


Agreed. Reference parameters (both C++-style references and pointers) should be avoided whenever possible. And between classes and exceptions, there's not often a good reason to return more than one value at a time.


"Sneftel is correct, if rather vulgar." --Flarelocke

[edited by - sneftel on January 25, 2004 9:33:40 PM]

Share this post


Link to post
Share on other sites
I almost never pass by non-const reference. If I do, though, I will comment it and make sure it is obvious from the name of the function. I use const references instead of pointers because I don''t like to constantly dereference the pointer, but I still don''t want the copy constructor to be called.

Share this post


Link to post
Share on other sites
I like pass-by-pointer when you want to pass an optional parameter. If the pointer is null then you obviously don't dereference it. I'll declare the function with null default values for the simple case.

Example:

// Declaration in class header:

CObject* GetNearestObject(float* pDistance = 0);

// Implementation:

CObject* CObject::GetNearestObject(float* pDistance)
{
CObject* pNearestObject;
float NearestDistance;
....
....

if (pDistance)
{
*pDistance = NearestDistance;
}
return pNearestObject;
}


That gives you the choice of calling the function as say MyObject.GetNearestObject() or MyObject.GetNearestObject(pDistance), depending on what your needs are.

Value of good ideas: 10 cents per dozen.
Implementation of the good ideas: Priceless.

Proxima Rebellion - A 3D action sim with a hint of strategy

[edited by - BS-er on January 25, 2004 9:50:20 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by BS-er
I like pass-by-pointer when you want to pass an optional parameter. If the pointer is null then you obviously don''t dereference it. I''ll declare the function with null default values for the simple case.

Example:

// Declaration in class header:

CObject* GetNearestObject(float* pDistance = 0);

// Implementation:

CObject* CObject::GetNearestObject(float* pDistance)
{
CObject* pNearestObject;
float NearestDistance;
....
....

if (pDistance)
{
*pDistance = NearestDistance;
}
return pNearestObject;
}


Value of good ideas: 10 cents per dozen.
Implementation of the good ideas: Priceless.

Proxima Rebellion - A 3D action sim with a hint of strategy

[edited by - BS-er on January 25, 2004 9:45:05 PM]


Or you could overload.

Share this post


Link to post
Share on other sites
As some others here, I always use pointers for data that will, or could be, manipulated within the function.

As for dereferencing, when passing pointers it''s usually to larger structs or classes, and to access their members, the dereferencing then becomes the task of using and ''->'' instead of a ''.''. Again this makes it clearer what is really going on.

However, for functions that only use reference to get, and copy, data, like for initializing members in a constructor, c++ reference is probably a nicer and cleaner way of representing it. It will however be descrete to the user of the class/function, and he will just have to hope and pray you''re not passing his large struct by copy .. at least he won''t have to be bothered writing ''&''s all over the place

Share this post


Link to post
Share on other sites
quote:
Original post by Sneftel
quote:
Original post by Doc
I try to avoid writing functions that manipulate parameters like that.


Agreed. Reference parameters (both C++-style references and pointers) should be avoided whenever possible. And between classes and exceptions, there''s not often a good reason to return more than one value at a time.
Unless you want to fill in a C-string. But since we already have std::string, it doesn''t matter now.

Share this post


Link to post
Share on other sites
References were added to C++ to make the syntax of operator overloading feasible:


struct MyArray
{
Stuff& operator[](int i);
const Stuff& operator[](int i) const;
};



What is important when using them, is to make certain you are not making ''write only code'' (you only know what it does when you write it). It ought to be obvious from the function name that the parameter is mutated. e.g. We do not expect std::find to change what we pass to it, but we expect std::replace to.

Other than operator overloading, I rarely see non-const references.

Share this post


Link to post
Share on other sites