Passing structs by pointer rather than reference
-
I've often wondered what is the reasoning behind passing structs by pointers rather than by reference. Can anyone give me a good motivation for choosing one over the other? I see it all the time in MFC -- is it just MS standard? For instance, if I have the following:
typedef struct POINT
{
double x;
double y;
} tagPOINT, *LPPOINT;
void GetCurrLoc(LPPOINT pt)
{
pt->x = 3.2;
pt->y = 2.4;
}
void GetCurrLoc(POINT& pt)
{
pt.x = 3.2;
pt.y = 2.4;
}Is one any better than the other, besides the fact that passing by pointer is (slightly) easier when using dynamically allocated structs. Thanks, Dean
when passing objects ( struct ) by pointer, you always need to check the incoming pointer for NULL. if you pass by reference, you are sure that the class/struct is valid. Max.
-
when passing objects ( struct ) by pointer, you always need to check the incoming pointer for NULL. if you pass by reference, you are sure that the class/struct is valid. Max.
I'm sorry, but that is a false statement. Look at this code:
struct SomeStruct { ... };
SomeStruct& func() {
SomeStruct s;
return s;
}void func2(SomeStruct& s) {
s.DoTheFunkyStuff();
}func2(func());
So, just because it's a reference doesn't guarantee its validity. I feel that references are in the C++ language because it's syntactic sugar. I have no proof of this being the case, but I just can't find any other reasonable explanation for it. -- Only in a world this shitty could you even try to say these were innocent people and keep a straight face.
-
I'm sorry, but that is a false statement. Look at this code:
struct SomeStruct { ... };
SomeStruct& func() {
SomeStruct s;
return s;
}void func2(SomeStruct& s) {
s.DoTheFunkyStuff();
}func2(func());
So, just because it's a reference doesn't guarantee its validity. I feel that references are in the C++ language because it's syntactic sugar. I have no proof of this being the case, but I just can't find any other reasonable explanation for it. -- Only in a world this shitty could you even try to say these were innocent people and keep a straight face.
Returning a reference to a object declared on the stack in a function is wrong and bad coding! and will generate a very basic compiler warning ( level 1 ): It's only a warning because ( I think ) references are implemented as pointers. from MSDN : Compiler Warning (level 1) C4172 returning address of local variable or temporary A function returns the address of a local variable or temporary object. Local variables and temporary objects are destroyed when a function returns, so the address returned is not valid. Redesign the function so that it does not return the address of a local object. Max.
-
I'm sorry, but that is a false statement. Look at this code:
struct SomeStruct { ... };
SomeStruct& func() {
SomeStruct s;
return s;
}void func2(SomeStruct& s) {
s.DoTheFunkyStuff();
}func2(func());
So, just because it's a reference doesn't guarantee its validity. I feel that references are in the C++ language because it's syntactic sugar. I have no proof of this being the case, but I just can't find any other reasonable explanation for it. -- Only in a world this shitty could you even try to say these were innocent people and keep a straight face.
-
I've often wondered what is the reasoning behind passing structs by pointers rather than by reference. Can anyone give me a good motivation for choosing one over the other? I see it all the time in MFC -- is it just MS standard? For instance, if I have the following:
typedef struct POINT
{
double x;
double y;
} tagPOINT, *LPPOINT;
void GetCurrLoc(LPPOINT pt)
{
pt->x = 3.2;
pt->y = 2.4;
}
void GetCurrLoc(POINT& pt)
{
pt.x = 3.2;
pt.y = 2.4;
}Is one any better than the other, besides the fact that passing by pointer is (slightly) easier when using dynamically allocated structs. Thanks, Dean
When using non-dynammically allocated structures or when accessing elements of an array, the reference version is easier and visually cleaner. Also, it would be wise to place consts on both those arguments to provide hints to the compiler. References really start to shine when you start getting into operator overloading. Tim Smith I'm going to patent thought. I have yet to see any prior art.
-
When using non-dynammically allocated structures or when accessing elements of an array, the reference version is easier and visually cleaner. Also, it would be wise to place consts on both those arguments to provide hints to the compiler. References really start to shine when you start getting into operator overloading. Tim Smith I'm going to patent thought. I have yet to see any prior art.
Ah yes, lpObject->operator[](index) is rather ugly, huh? So as far as I can see, there is no real reason to use one over the other, other than for cleanliness of the code. As for the consts, I got you on that one -- neither can be const since they are both modified by the called function. ;) Thanks everyone for the responses. --Dean
-
Returning a reference to a object declared on the stack in a function is wrong and bad coding! and will generate a very basic compiler warning ( level 1 ): It's only a warning because ( I think ) references are implemented as pointers. from MSDN : Compiler Warning (level 1) C4172 returning address of local variable or temporary A function returns the address of a local variable or temporary object. Local variables and temporary objects are destroyed when a function returns, so the address returned is not valid. Redesign the function so that it does not return the address of a local object. Max.
Yes, and so is using a pointer to a previously deleted object. It is bad yes, but it is still possible. Thus you can't rely on references being always correct. I know my example was trivial and is obviously erroneous, but I'm still right ;P -- There's a new game we like to play you see. A game with added reality. You treat me like a dog, get me down on my knees. We call it master and servant.
-
That is a bug in the program which is a different beast. As the standard states, a well defined program can't have a NULL reference where a pointer can have a NULL pointer. Tim Smith I'm going to patent thought. I have yet to see any prior art.
Yes, it was a bug - and what software is 100% bug free? Tim Smith wrote: As the standard states, a well defined program can't have a NULL reference where a pointer can have a NULL pointer. True. But just as pointers can be dangling, references can too as I demonstrated. NULL is just one "bad" value out of 232 possible values on a contemporary 32 bit machine. Most of the other 232 - 1 aren't (most likely) legal. I am arguing that the statement "if you pass by reference, you are sure that the class/struct is valid" is false - something which I believe I demonstrated with perhaps an easy to spot "error". However, as you point out, a reference can't ever be NULL1. 1 In an environment where you can do *((SomeClass*)NULL) = SomeClass();, what is SomeClass& ref = *((SomeClass*)NULL);? You could, if you really wanted to, do that in DOS. :) -- There's a new game we like to play you see. A game with added reality. You treat me like a dog, get me down on my knees. We call it master and servant.
-
Returning a reference to a object declared on the stack in a function is wrong and bad coding! and will generate a very basic compiler warning ( level 1 ): It's only a warning because ( I think ) references are implemented as pointers. from MSDN : Compiler Warning (level 1) C4172 returning address of local variable or temporary A function returns the address of a local variable or temporary object. Local variables and temporary objects are destroyed when a function returns, so the address returned is not valid. Redesign the function so that it does not return the address of a local object. Max.
Or what about this one?
class SomeClass {
RefClass& ref;
public:
SomeClass(RefClass& ref_) : ref(ref_) { ... }
};.... somewhere in 106 lines of code ....
RefClass* pRef = new RefClass();
SomeClass* pObj = new SomeClass(*pRef);.... somewhere else among those 106 lines of code ....
delete pRef;See what I mean? SomeClass::ref isn't valid. Yes it's a bug, but you can't say that ref is valid after the delete pRef. Same thing goes for pointers to object. Just because a pointer is not NULL doesn't make it valid. That's a dangling pointer, and as you can see, there are also dangling references. In both cases you have a bug on your hands, but it still doesn't make your previous statement true, which was my main argument all along. :) BTW, you can do this in VS.NET and most likely VC6:
struct Test { int x; };
int _tmain(int argc, _TCHAR* argv[])
{
Test& ref = *((Test*)NULL);
return 0;
}No crash, no nothing. Yet, ref will reference "an object" at NULL. Put a breakpoint on return 0 and you'll see. :) I still believe that the only advantage of references over pointers are purely syntactical. -- There's a new game we like to play you see. A game with added reality. You treat me like a dog, get me down on my knees. We call it master and servant.
-
Yes, it was a bug - and what software is 100% bug free? Tim Smith wrote: As the standard states, a well defined program can't have a NULL reference where a pointer can have a NULL pointer. True. But just as pointers can be dangling, references can too as I demonstrated. NULL is just one "bad" value out of 232 possible values on a contemporary 32 bit machine. Most of the other 232 - 1 aren't (most likely) legal. I am arguing that the statement "if you pass by reference, you are sure that the class/struct is valid" is false - something which I believe I demonstrated with perhaps an easy to spot "error". However, as you point out, a reference can't ever be NULL1. 1 In an environment where you can do *((SomeClass*)NULL) = SomeClass();, what is SomeClass& ref = *((SomeClass*)NULL);? You could, if you really wanted to, do that in DOS. :) -- There's a new game we like to play you see. A game with added reality. You treat me like a dog, get me down on my knees. We call it master and servant.
It certainly is possible to pass a reference to NULL:
struct Stuff {
...
};void StuffFunction(Stuff &stuff_item);
...
Stuff *stuff_pointer = NULL;
StuffFunction(*stuff_pointer);The compiler treats the "reference to dereferenced pointer" object as an 'identity' case, and just passes the value of the pointer, which in this case is NULL. In this case, inside the StuffFunction you can't tell that NULL has been passed in. The point behind the debate is that references are not inherently 'safer' than using pointers. They can be syntactically more convenient. Pointers are easier to get sloppy with if you're not careful.
Software Zen:
delete this;
-
It certainly is possible to pass a reference to NULL:
struct Stuff {
...
};void StuffFunction(Stuff &stuff_item);
...
Stuff *stuff_pointer = NULL;
StuffFunction(*stuff_pointer);The compiler treats the "reference to dereferenced pointer" object as an 'identity' case, and just passes the value of the pointer, which in this case is NULL. In this case, inside the StuffFunction you can't tell that NULL has been passed in. The point behind the debate is that references are not inherently 'safer' than using pointers. They can be syntactically more convenient. Pointers are easier to get sloppy with if you're not careful.
Software Zen:
delete this;
Gary R. Wheeler wrote: It certainly is possible to pass a reference to NULL: I know, I tried it in VS.NET the other night. :) I was just too tired to mention it, and it didn't really have any relevance with respect to my argument. Gary R. Wheeler wrote: In this case, inside the StuffFunction you can't tell that NULL has been passed in. Well, you could always do
if(&stuff_item == NULL)
, assuming Stuff doesn't overrideoperator&
. Gary R. Wheeler wrote: Pointers are easier to get sloppy with if you're not careful. The only extra support a reference gives you is that you have to initialize it. Which is certainly nice since the compiler can yell Error! I think I'll experiment some tomorrow to see if I can eliminate the use of pointers (to see if it's possible). I have some ideas I want to try out... :) -- There's a new game we like to play you see. A game with added reality. You treat me like a dog, get me down on my knees. We call it master and servant.