views:

109

answers:

2

Hi,

I am having some trouble figuring out the syntax for typedef reinterpret_cast. Can anyone help?

EDIT

What I am trying to do. I am always hesitant as people seem to get caught up in every thing else except what the problem actually is as you can see with my last post which lead to a whole bunch of nothing.

I am trying to come up with a way of assigning mem address 0 to pointers. I use this as safety catches etc. I was lead to believe that typedef cast would help in this. Please do not advise me to use NULL.

Thanks

+1  A: 

You mean like?

sometype *foobar = 0;

Assigning pointers with a null-value is something you have to do manually in C/C++. If you're looking for a way to have it auto-init to null, take a look at pointer wrapping classes like autoptr or smartptr classes.

Victor T.
+4  A: 

I think I finally understand what you want, but I'm still not sure why you want it, and I suspect that you don't really need it. If you would tell us what your ultimate goal is, we might be able to tell you what you really need. That said:

You seem to be aware that

Foo* p = 0;

is defined as setting p to be a null pointer, which may or may not actually be represented by a string of zero-bits in memory. You seem to want a way to ensure that the memory occupied by the pointer is full of zero bits, rather than whatever bit pattern represents the null pointer.

Here are two ways you might do this. The most straightforward and correct is simply:

Foo* p;
memset(&p, 0, sizeof(p));

Another, which seems to be what you were thinking of with the reinterpret_cast, is this:

Foo* p;
int i = 0;
p = reinterpret_cast<Foo*>(i);

The reason that this works and assigning p directly to zero does not is because only literal zeros are interpreted as the null pointer when assigned to pointers. i contains the value zero, but is not a literal zero. The above is wrong, though, when pointers and integers aren't the same size, so a better method might be:

Foo* p;
char c[sizeof(p)] = {0};
p = reinterpret_cast<Foo*>(c);

However, this is still not correct because it is undefined behavior to access the result of a reinterpret_cast when you're lying about the real type of the variable you cast. c is not really a Foo* above, so this is undefined behavior. Thus, you should use memset to achieve this instead.

The reason you seemed to want a typedef is so that you could have a pointer type that is automatically assigned the value 0 when created. Unfortunately, this is not possible. A typedef can only specify a type, not an initial value. Apart from creating your own smart-pointer class to do this, the best you could do is wrap up the call to memset in a convenience function, e.g.

template <typename T> T* zeroPointer() {
   T* p;
   memset(&p, 0, sizeof(p));
   return p;
}

Foo* p = zeroPointer<Foo>();

Now, even given all of that, this still may not give you what you want in all cases. As GMan pointed out in his comments, it's not guaranteed that pointers are represented by numbers on all platforms, so the value of p may not be numeric zero after this, and may not correspond to address 0 on the system, even if it is all zero-bits. A given system may not even have such a thing as an "address 0". For example, on a particular system, a pointer may be represented by a struct containing a segment address and an offset.

Finally, be aware that you will have to go to extra pains to test for this value. For example:

Foo* p = zeroPointer<Foo>();

if (p == 0) {
  // Not reached if NULL is not all-zero bits, since the literal 0 in the
  // comparison is interpreted as a null pointer constant
}

You would essentially have to check each bit individually. The only way to do this without invoking undefined behavior is something like this:

template <typename T> bool isZero(T& p) 
{
   char c[sizeof(p)];
   memcpy(&c, &p, sizeof(p));
   for (int i = 0; i < sizeof(p); ++i) {
     if (c[i] != 0) return false;
   }
   return true;
}

Foo* p = zeroPointer<Foo>();

if (isZero(p)) {
  // Always reached
}

This is all pretty cumbersome, because you're working against the language here. The language is trying to be helpful by giving a portable method of setting null pointers, but you want to eschew that and make up your own all-zero-bits pointer for some reason. That's why I'm convinced that whatever it is that you ultimately want to do can be done in some other way that doesn't involve fighting the language you're programming in.

Tyler McHenry