-4

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

Blachshma
  • 17,097
  • 4
  • 58
  • 72
Thomas
  • 2,939
  • 6
  • 32
  • 29
  • 1
    Can you provide an example of what you want to achieve? – Anthony Jul 23 '10 at 02:57
  • 4
    "typedef reinterpret_cast" is a meaningless phrase like "fish existentialism" or "firehose dissonance". What are you trying to do? – Tyler McHenry Jul 23 '10 at 02:57
  • Maybe something like `typedef reinterpret_cast RICI` is what he is looking for so he can call `RICI(theInt);` in his code? – Anthony Jul 23 '10 at 03:01
  • @Duracell: Then he'd need to use a macro, not a typedef. There is no typedef syntax for what you propose. – Billy ONeal Jul 23 '10 at 03:04
  • @Billy ONeal, yeah I thought so. It's probably more readable to just use the full statement in the code rather than cut corners with it. – Anthony Jul 23 '10 at 03:05
  • 11
    @Thomas Okay, if that's *not* what you're trying to do, can you give an example of what you *are* trying to do? This is a situation where you're asking "How do I get glass out of pickles?" when you should be asking "I have a jar of pickles and would like to eat them, what should I do?" Because then we could tell you to unscrew the lid, and that smashing the jar with a hammer isn't the right way to do it. – Tyler McHenry Jul 23 '10 at 03:07
  • 2
    You're still saying technically nonsensical things. 0 is an integer, addresses are not necessarily integers, you can't necessarily assign the value 0 to a pointer. You can say `ptr = 0` giving it a null-pointer value (exactly the same as saying `ptr = NULL`). Give us *real* situations and problems, not *steps*. We're here to tell you the steps. Honestly, your understanding seems a bit shaky, perhaps a [good book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) would help. – GManNickG Jul 23 '10 at 06:04
  • If you look in a conforming C++ cstdio or stdio.h header, you will see "#define NULL 0". Therefore NULL *is* 0. – Michael J Jul 23 '10 at 12:47
  • 2
    @Michael J True, but misleading. In C++, the literal `0` is interpreted as whatever the system represents a null pointer as when in a pointer context. So it's correct to say that `NULL` (the constant) is `0` (the literal), but it's not correct to say that null (the concept) is zero (the number), since the literal `0` is mapped to a concept of null that may or may not be a numeric zero. – Tyler McHenry Jul 23 '10 at 12:51
  • What is wrong with NULL? – josefx Jul 23 '10 at 13:07
  • 3
    @Thomas: take a step back. Why are you trying to assign memory address zero to a pointer, and why isn't NULL acceptable? What *problem* are you trying to solve? *Why do you need these pointers to point to address 0?* – jalf Jul 23 '10 at 18:11
  • @Tyler - The preprocessor changes "NULL" to "0" throughout the code. By the time the compiler sees it, there is no difference. It is sometimes useful (conceptually) to think about NULL separately, but under the hood there is no difference. When @Thomas says he cannot use NULL, I think he may be confused. – Michael J Jul 25 '10 at 04:22
  • @Michael I understand that. However, there is another layer to this issue. The preprocessor replaces `NULL` with `0`, but the *compiler*, when a literal `0` is assigned to or compared with a pointer, treats the `0` as whatever the system's internal representation of a null pointer is, which may not be all-zero-bits. Granted, on nearly all commonly used systems it *is* all-zero-bits, but that isn't required by the C or C++ standards. – Tyler McHenry Jul 25 '10 at 23:56

3 Answers3

5

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
  • 74,820
  • 18
  • 121
  • 166
1

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.

greatwolf
  • 20,287
  • 13
  • 71
  • 105
0

reinterpret_cast isn't a type, so you can't typedef it. You can wrap it in a template, though:

template<typename T> T* improved_null()
{
    return reinterpret_cast<T*>(0);
}

int* foo = improved_null<int>();

It so happens that you don't actually need the reinterpret_cast in this case (a function's return value is coerced to the correct type if necessary):

template<typename T> T* improved_null() { return 0 }

Of course, if you want an improved NULL, you may consider nullptr.

Max Lybbert
  • 19,717
  • 4
  • 46
  • 69