Author Topic: Defensive programming  (Read 4432 times)

0 Members and 1 Guest are viewing this topic.

Offline blackhole

  • Still not over the rainbow
  • 29
  • Destiny can suck it
    • Black Sphere Studios
Defensive programming
Quote from: Worse Than Failure
"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

 

Offline Flipside

  • əp!sd!l£
  • 212
Re: Defensive programming
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.

 
Re: Defensive programming
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
STRONGTEA. Why can't the x86 be sane?

 

Offline blackhole

  • Still not over the rainbow
  • 29
  • Destiny can suck it
    • Black Sphere Studios
Re: Defensive programming
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.

 

Offline Flipside

  • əp!sd!l£
  • 212
Re: Defensive programming
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.

 

Offline Mongoose

  • Rikki-Tikki-Tavi
  • Global Moderator
  • 212
  • This brain for rent.
    • Minecraft
    • Steam
    • Something
Re: Defensive programming
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.

 

Offline Bobboau

  • Just a MODern kinda guy
    Just MODerately cool
    And MODest too
  • 213
Re: Defensive programming
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.
Bobboau, bringing you products that work... in theory
learn to use PCS
creator of the ProXimus Procedural Texture and Effect Generator
My latest build of PCS2, get it while it's hot!
PCS 2.0.3


DEUTERONOMY 22:11
Thou shalt not wear a garment of diverse sorts, [as] of woollen and linen together

 
Re: Defensive programming
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:
Code: [Select]
bool MyClass::ReturnTrue()
{
  return true;
}
MyClass* class = 0;
class->ReturnTrue(); //will return true
would return true without any problem
Code: [Select]
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.

 

Offline blackhole

  • Still not over the rainbow
  • 29
  • Destiny can suck it
    • Black Sphere Studios
Re: Defensive programming
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

 
Re: Defensive programming
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 :)

 

Offline blackhole

  • Still not over the rainbow
  • 29
  • Destiny can suck it
    • Black Sphere Studios
Re: Defensive programming
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*

 
Re: Defensive programming
I do offer the following example from the ATL/MFC headers

Code: [Select]
_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):
Code: [Select]
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
Code: [Select]
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.
« Last Edit: May 16, 2009, 10:05:11 am by portej05 »
STRONGTEA. Why can't the x86 be sane?

 

Offline blackhole

  • Still not over the rainbow
  • 29
  • Destiny can suck it
    • Black Sphere Studios
Re: Defensive programming
That's exactly what I said :P

 

Offline Mika

  • 28
Re: Defensive programming
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:
Quote
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.
Relaxed movement is always more effective than forced movement.