The following snippet from a DirectX tutorial I'm reading:
I'm a little confused about the (void**) cast. Isn't &pVoid a void** anyway?Code:VOID* pVoid; v_buffer->Lock(0, 0, (void**)&pVoid, 0);
The following snippet from a DirectX tutorial I'm reading:
I'm a little confused about the (void**) cast. Isn't &pVoid a void** anyway?Code:VOID* pVoid; v_buffer->Lock(0, 0, (void**)&pVoid, 0);
Last edited by Sharke; 05-10-2009 at 12:06 AM.
That depends, what did you really do with VOID? VOID isn't a keyword, void is.
Quzah.
Hope is the first step on the road to disappointment.
1. VOID is Microsoft Windows API type
2. &pVoid has type VOID** - which is exactly what the function expects - so no cast is needed
3. cast to void** is strongly speaking - wrong thing to do because it is not guaranteed that VOID will always be a synonim to void
All problems in computer science can be solved by another level of indirection,
except for the problem of too many layers of indirection.
– David J. Wheeler
I agree with vart. It looks like a potential bug in the tutorial.
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
It certainly seems logical to think so. However, I was just looking through a book by Jonathan Harbour today and when he shows how to lock the vertex buffer in DirectX he does exactly the same thing - casts that argument to void**. I've looked around and seen other tutorials which also cast to void** the same way.
Here's a page of a book by Alan Thorn which also does the cast:
DirectX 9 Graphics: The Definitive ... - Google Book Search
I think everyone's response is trying to get at that because VOID is probably a #define or typedef, and not a C/C++ primitive, you can't guarantee that it's compatible with void.
**VOID may not be **void
Environment: OS X, GCC / G++
Codes: Java, C#, C/C++
AOL IM: neandrake, Email: neandrake (at) gmail (dot) com
But if the specification for a function states that it requires a VOID** , then isn't the required guarantee that the argument is VOID**? Thus if, in this case, the actual argument is &pVoid and pVoid has already been defined as a VOID*, then I don't see why it needs a cast to guarantee that it's void**, which isn't the required type stated in the specification anyway. Or maybe I'm just missing something here.
That's right.Originally Posted by Sharke
However, it is also possible that you could be looking at a change in programming interface, e.g., the tutorial and some books were written for a time when Lock's third parameter was a void**, but later it was changed to a VOID**.
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
Maybe - but since most of these tutorials also clearly state the DirectX specification which says VOID**, I'm thinking that it's possibly the case that they contain code which has been copied and pasted again and again over the years, or the authors have just come to learn it parrot fashion and have never thought about updating.
Does anybody know what difference between void * and void ** and void *** ?
Where is it can be useful ?
Who can get an address from void ** ?
Yes. They are pointer types with different levels of indirection.Originally Posted by c.user
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
Originally Posted by laserlightif we would write pp = &n; p = &pp what we will get then ?Code:void *p, **pp; int n; p = &n; pp = &p;
I mean, does anything change in the program ?
Or, we only will get an error for pp = &n and nothing more will change ?
While technically true, any API that defines a symbol VOID which means something other than "void" is just being purposefully confusing and should not be used. Probably, this is a holdover from days when not all compilers supported the void type, and the only real alternative would be char.
Similarly, if you see some constant FALSE in a piece of code, you technically should not assume that this means 0, but if it doesn't, you should run, not walk, as far from that codebase as possible.
Code://try //{ if (a) do { f( b); } while(1); else do { f(!b); } while(1); //}