Hard Light Productions Forums
Off-Topic Discussion => Programming => Topic started by: blackhole on May 15, 2009, 06:08:46 pm
-
"Some programmers like to program defensively," wrote Sam, "and then there's some of my coworkers. This is found at the top of nearly every function of our C++ classes."
if (!this) return false;
OW
-
I'm a contract man myself, if the wrong data is getting to your subroutines, then you should be taking things higher in the code, not bogging down your basic functions with checks, especially if it's a frequently called function, before you know it, you're performing checks that, on many occasions, shouldn't need to take place, every time the routine is called.
-
Personally, it depends if I'm writing library code or writing front-end code.
In the library, you do need to check and assert on NULLs (although, doing it in a class is probably REAL overkill), but in the front-end, you've got total control over stuff, so sometimes those checks aren't always necessary
-
They are checking to see if the THIS pointer is null. The freaking THIS POINTER! It the this pointer is null YOU COULDNT BE CALLING THE FUNCTION IN THE FREAKING FIRST PLACE.
-
Well, I'm not a C++ programmer, but yes, that looked somewhat ridiculous to me too, I think that's why I didn't bother commenting on it, because it's just too daft to make sense, it couldn't be null.
I must admit to never having been a large fan of the THIS function in the first place, I can understand its need to exist, but I've always felt it has the potential to be misunderstood and over-used, as that little bit of code exemplifies.
-
It took me a Google search to even understand what was going on here, since "this" never came up in my few comp. sci. classes at school. But yeah...ow.
-
it, could happen, I've seen it happen, but returning false is almost certainly the wrong thing to do here. throwing an error of some sort would probably be the better way to go.
-
They are checking to see if the THIS pointer is null. The freaking THIS POINTER! It the this pointer is null YOU COULDNT BE CALLING THE FUNCTION IN THE FREAKING FIRST PLACE.
Wrong:
bool MyClass::ReturnTrue()
{
return true;
}
MyClass* class = 0;
class->ReturnTrue(); //will return true
would return true without any problem
bool MyClass::ReturnTrue()
{
return true;
}
//is converted by the compiler to:
bool MyClass::ReturnTrue(MyClass*)
{
return true;
}
class-> ReturnTrue(); //is converted by the compiler to:
ReturnTrue(class);
//well, not exactly, but you get the idea
So, unless you do access member variables of the class, invoking a function on 0 is possible and valid.
Still, such checks are pointless in nearly all cases imho.
-
That is true, but you should always always always check to ensure the pointer your using is not NULL before calling a function in a situation where it could be null, and if you ever DO call a function from a null pointer, you did something wrong. Therefore I should revise my statement to you SHOULDN'T be calling the function in the first place (I've had many bugs where the call stack would get corrupted because something returned an invalid pointer and I ended up calling a function on it).
But yes, the this pointer is really just another argument passed to the function in the EAX register, since computers aren't really object oriented. That doesn't make it any less stupid :p
-
Therefore I should revise my statement to you SHOULDN'T be calling the function in the first place (I've had many bugs where the call stack would get corrupted because something returned an invalid pointer and I ended up calling a function on it).
I can only agree with you here :)
-
Therefore I should revise my statement to you SHOULDN'T be calling the function in the first place (I've had many bugs where the call stack would get corrupted because something returned an invalid pointer and I ended up calling a function on it).
I can only agree with you here :)
SOMEONE AGREES WITH ME!
*Erik has a heart attack and dies*
-
I do offer the following example from the ATL/MFC headers
_AFXWIN_INLINE CGdiObject::operator HGDIOBJ() const
{ return this == NULL ? NULL : m_hObject; }
(there are a bunch of other examples in there as well)
When I've figured out why it could be NULL, I'll stick it here\
EDIT: Here's a case you may not have considered (although, it is almost certainly a coding error):
MyAwesomeClass* pMAC = CreateNewAwesomeClass( );
pMSC->DoCoolFunction( );
If the function CreateNewAwesomeClass fails for some reason, and returns NULL, the call to DoCoolFunction will be done with the this pointer as NULL.
Another good reason why you should always check function return values.
EDIT2: Another bloody good reason to initialise your variables
MyAwesomeClass* pMAC;
pMAC->DoCoolFunction( );
The value of pMAC is NOT defined, and if the initialisation is skipped for any reason, a junk address will be referenced, and that is something that you cannot protect against.
-
That's exactly what I said :P
-
I don't know about defensive programming, there seems to be some pretty good stuff on multiple sources why you should always check the stuff that's getting inside a function.
Ten Commandments of C
http://www.lysator.liu.se/c/ten-commandments.html
Commandment 3:
Thou shalt cast all function arguments to the expected type if they are not of that type already, even when thou art convinced that this is unnecessary, lest they take cruel vengeance upon thee when thou least expect it.
I'm considering breaking that one.