Archived

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

vbisme

pointer = 0 same as pointer = null?

Recommended Posts

Sometimes. It all depends on which library sets it. For most console apps, that would be the iostream library, which defines NULL as 0, so the answer in that case is yes. I''m not certain of the ANSI standard definition, but I think it''s something like a void pointer to 0. It''s all the same, in effect.

Later,
ZE.

//email me.//zealouselixir software.//msdn.//n00biez.//
miscellaneous links

[if you have a link proposal, email me.]

Share this post


Link to post
Share on other sites
well on most systems NULL would be 0 since that (and 0xFFFFFFFF on a 32bit system) are the two best values to use since things should not be allocated that low (reserved for system stuff like the vector interupt table, etc.). i ussually use NULL, but just to give myself an easier time reading code (especially functions that accept pointers).

Share this post


Link to post
Share on other sites
This brings me to a question. Often in C++ code we see a line like:

if (!MyPointer)
{
...
}

now this would assume that NULL==0 so my question is is this a safe practice? or is it preferred if we do:

if (MyPointer == NULL)

Thanks

Share this post


Link to post
Share on other sites
I do the first one (saves keystrokes). I''m not aware of any portability issues with it either.


Mike

"The state is that great fiction by which everyone tries to live at the expense of everyone else." - Frederick Bastiat, The Law

Share this post


Link to post
Share on other sites
Poya, C/C++ compilers only allow pointers to be tested against zero if you don't use typecasting. So if( !Pointer ) is always safe and will always work, assuming you set your pointers to zero (or NULL or whatever) to indicate they're invalid.

Technically, pointers can be any value. It all depends on how you want to treat it. You can set pointers to 0xFFFFFFFF to indicate they're invalid if you wish, if you use typecasting. if( (UINT)Pointer != 0xFFFFFFFF) though there's no real reason to do it that way.

~CGameProgrammer( );



Edited by - CGameProgrammer on February 6, 2002 11:55:23 PM

Share this post


Link to post
Share on other sites
quote:
Original post by vbisme
What about a call to:

delete this;

is that safe?


I have scanned through the standard and they not prohibit it.

But be wary of those thing for a call like this to work:

1. must not be from a destructor(because delete will call the destructor )
2. You must be sure that the class was allocated on the stack.

So a class like this would work.


  

class Test
{
void func()
{
delte this;
}
};


Test* t = new Test();

t->func(); //this is ok. Do NOT CALL DELETE ON THE OBJECT AFTER THAT THOUGH!!


Test obj;

obj.func(); //NOT ok. program behavior will go from seem to work well to crap out.



I do not see much use for that.

Share this post


Link to post
Share on other sites
an example use for calling delete on this would be in a reference-counting situation, where there may be many other objects holding a pointer to an object. In this case, a good way to solve the problem of who cleans up is having the object destroy itself when there are no more references:

    
class Foo
{
private:
int m_intRefCount;


public:
...


void AddRef() // called when you take a pointer to the object

{
++m_intRefCount;
}


void Release()
{
--m_intRefCount;
if( m_intRefCount == 0 )
{
delete this;
}
}

};


my brain is feeling a bit rusty today, but i think this is how COM works (can anyone confirm?)


[edit] doh... forgot to mention that the other objects then call Release() on the object when they are finished with it, rather then explicitly deleting it. However, once you call Release(), you should treat the object as being deleted/invalid (even though it may not be)

Edited by - Bad Monkey on February 7, 2002 3:18:08 AM

Share this post


Link to post
Share on other sites
That''s how COM works, yeah. Also, when figuring out the answer to questions like these, it helps to remember how member functions work. Object::Function() really works like Object_Function(Object *this). So deleting this is fine as long as you don''t try to access any member variables of it (though you can still access member functions even if it''s deleted, as long as they too don''t access any member variables.

You can try writing your own COM-type stuff that keeps a list of pointers to an object and sets them all to NULL when the object is destroyed. So if you call Obj->Release() and nothing else references it, Obj would be set to NULL.

~CGameProgrammer( );

Share this post


Link to post
Share on other sites
Excerpt from stdlib.h:
  
#ifdef __cplusplus
#define NULL 0
#else
#define NULL (void*)0
#endif


Personally, I use NULL only on pointers, and 0 only on numeric variables.
int a = 0;
float b = 0;
char* c = NULL;
int* d = NULL;
MyStruct e = {0};
MyStruct* f = NULL;
That''s all there is to it.

-----------------------------
The sad thing about artificial intelligence is that it lacks artifice and therefore intelligence.

Share this post


Link to post
Share on other sites
One this about putting delete this in the destructor:

if:

SomeClass::~SomeClass()
{
delete this;
}

woudl cause problem:

but:

SomeClass::~SomeClass()
{
if (this)
{
delete this;
}
}

Would that not be fine?

Share this post


Link to post
Share on other sites
'delete this' is fine in a function for reference counting, but I can never see a time that you'd need to call 'delete this' from the destructor. It's a redundant call and just looks complicated. If I saw something like that while reading through someone's code, I'd have to call them on the phone and ask them what was going on. Basically, I'd be confused.

Oh, and as to the original question, I think referring to pointers as equalling 0 makes code less readable too. If you see just the following two lines of code:

character_level = 0;
character_race = NULL;


You can tell which one is most likely a pointer and which is most likely an integer of some type. However, if you saw this:

character_level = 0;
character_race = 0;

You'd have no idea and I'd just assume both were integers.



Edited by - JonStelly on February 7, 2002 2:17:25 PM

Share this post


Link to post
Share on other sites
thats where name decoration is useful JonStelly

all my variables are prefixed with their scope and type... it makes it soooo much easier to track them that way.

e.g.
- g_intFred would mean Fred is a global integer
- m_dblBrainFunctionLeftAfterBigParty would be a member variable of a class (and obviously a double)
- l_ptrSomeObject would be a pointer to whatever, and be local within a function

Some may call this approach hideous and hard to read, but once you get used to a style like this, it is actually much easier (no going off to look up the definition). Plus, if you work in a team environment, it saves a lot of pain (the hard part is agreeing on a prefix format )

Don't get me wrong though... this combined with using NULL will make your code all the more readable... NULL just makes more sense than 0 in the context of pointers.


[edit]
As an aside, calling delete in a destructor is indeed very pointless... and if i am not mistaken, will create an infinite loop (calling delete invokes the destructor )

Edited by - Bad Monkey on February 7, 2002 9:32:24 PM

Share this post


Link to post
Share on other sites
Well that's a tough call. This is starting to sound like one of those 'you make the call' commercials from decades past.

Anyhow... on the one hand, I don't think of an abstract class's virtual function declarations as declaring a null pointer for the function, since you can't instantiate an instance of an abstract class directly, it just means you'll have to implement the function elsewhere.

But on the other hand, I don't think NULL makes the code any more difficult to read, other than the fact that most people use the '= 0' syntax so it's what they expect.

Edited by - JonStelly on February 8, 2002 3:38:54 AM

Share this post


Link to post
Share on other sites