Sign in to follow this  
BennettSteele

C++ Void* Questions

Recommended Posts

BennettSteele    493
I was wondering... i know a void* turns a variable into raw binary data. is it possible to have a void* be a pointer to another variable?


also, how would i store the address of the variables as a pointer?

int *p=0;//obviously

then store the address of p, so

a= point to p;

a=1;

//p is now 1

Share this post


Link to post
Share on other sites
void pointer simply means that an undefined type.
You can typecast it in whatever you like. (also all other types)

Example:
int* pixelArray = (int*)voidPtr;
Usually its a bad practice.. you must always think what your data is and what you do with it. But in some cases it can be unavoidable.

Pointer is an address.
So if you have a pointer of A, it means that the pointer contains the memory address where A is stored.

Share this post


Link to post
Share on other sites
BennettSteele    493
i see. why is it bad practice? im on the verge of using it where i need different types for the same variable, which is alot.
so this works?

bool a=true;

void foo(void* val)
{
//found its a bool
bool* nVal=(bool*)val;
if(nval==true){nval=false;}
}

foo((void*)&a);

Share this post


Link to post
Share on other sites
Cornstalks    7030
It works, yeah, but the real problem isn't the fact that you're using a void*. The real problem is that you need to do it a lot. That signals a design flaw in your program.

Share this post


Link to post
Share on other sites
one of the examples if you try to delete void pointer that points to a class it wont call the destructor of that class.
It also means that you have questionable architecture.

Can you tell me why do you want to use it and for what?

Share this post


Link to post
Share on other sites
BennettSteele    493
XD im writing some code for a menu button, which has to either point to a bool, int, float or string/char array somewhere in the program. it would be alot easier to have it point to a variable and tell it the class than to make seperate buttons for each variable.

Share this post


Link to post
Share on other sites
Washu    7829
Alternatively you can use a discriminate union, such as boost::variant. You can see a sample of using boost::variant [url="http://www.gamedev.net/topic/620069-c-cvar-system/page__view__findpost__p__4917994"]here[/url]

Share this post


Link to post
Share on other sites
SimonForsman    7642
[quote name='Vlad86' timestamp='1331183989' post='4920322']
Its cleaner to use inheritance in this case.
Button that is derived specific per type.
[/quote]

I'd probably use templates or a union if i need a class dealing with multiple parameter types. in C++ a discriminated union such as boost::variant is prefered over a normal C style union due to the added type safety, C unions however work well enough if you do something similar to the SDL_Event union, (a union of a 1 byte type identifier and a set of structs where the structs all start with a 1 byte type identifier aswell).

For a GUI a signals/slots, event or callback mechanism would be preferable to having buttons with pointers to data owned by other parts of the program.

Share this post


Link to post
Share on other sites
Tribad    981
[CODE]
if(nval==true){nval=false;}
[/CODE]

I think this is not what you intended to do. You compare the pointer nval with true not the value nval points to.
Comparing any pointer with a boolean in C++ is legal. Its an artifact from C where

[CODE]
if (ptr) do something
[/CODE]

compares the pointer against NULL. This is how pointer checking is done in a short form in C.
For C++ the pointer is converted to a boolean and afterwards compared.

You will not get a warning about that.
It shows a bit why type safe programming is a good thing and why void pointers should be avoided.

Share this post


Link to post
Share on other sites
Rattenhirn    3114
[quote name='bennettbugs' timestamp='1331182979' post='4920316']
i see. why is it bad practice? im on the verge of using it where i need different types for the same variable, which is alot.
so this works?

bool a=true;

void foo(void* val)
{
//found its a bool
bool* nVal=(bool*)val;
if(nval==true){nval=false;}
}

foo((void*)&a);
[/quote]

It's bad practice, because you're working around the type system of C and C++, so the compiler won't be able to check anything for you.

As others have pointed out, "union" can be used to treat one memory location as more than one type, but in this case, I'm sure there are even better ways using OO or templates.

One more thing: If you're using C++, also use C++ casts. In this case this one would be the correct one: bool* nVal=reinterpret_cast<bool*>(val);
This would make it clear to everyone what you're doing.

Share this post


Link to post
Share on other sites
the_edd    2109
[quote name='Rattenhirn' timestamp='1331203661' post='4920382']
One more thing: If you're using C++, also use C++ casts. In this case this one would be the correct one: bool* nVal=reinterpret_cast<bool*>(val);
[/quote]
You could use static_cast, in fact. The C++0x draft standard even defines reinterpret_casts between pointer types as if static_cast-ing through a void* intermediary (5.2.10.7).

Share this post


Link to post
Share on other sites
Kyall    287
I'm going to be pro union here. But I also strongly recommend against not using strong data types, have a look at templated functions or something first. But if no other option, use a union. From reading your description though, maybe try a template like:

[code]template <typename T> class MenuButton
{
public:
MenuButton( T* a_dataMember );
protected:
T* _dataMbr;
};[/code]

This allows you to have a separate class for each type, without actually writing all the code to do that. Use it like:

float val1 = 3.14f;
MenuButton<float> fButton = MenuButton<float>(&val1);
char* val2 = "SomeString";
MenuButton<char> strButton = MenuButton<str>(&val2);

And if you need to access these different types using one type, so if you're putting these types in a list, use inheritance like so:

[code]class MenuItemBase
{
// Stuff, abstract functions so you can actually use the child classes
};
template <typename T> class MenuButton : public MenuItemBase
{
// etc as above, except with some implementations of the abstract functions to allow you to use the class effectively
};[/code]

But keep in mind, that any functions you declare for a templated class, must be defined before they are used. So you will have to do this:

[code]// In the header file:
class MenuItemBase
{
public:
virtual void MyFunc(int&) = 0;
};
template <typename T> class MenuButton : public MenuItemBase
{
public:
virtual void MyFunc( int& x ) { x = 5; }
};
// Or this, also in the header file

class MenuItemBase
{
public:
virtual void MyFunc(int&) = 0;
};
template <typename T> class MenuButton : public MenuItemBase
{
public:
virtual void MyFunc( int& x );
};
template <typename T> void MenuButton<T>::MyFunc(int& x)
{
x = 5;
}
// Instead of more normal header class declaration then cpp class definition [/code]

I'm sorry that that's the way you'll have to define a template class, but take it up with those pricks on the c++ standards board who decided to make the export keyword a blank reserved keyword than to have to do any work whatsoever on their compilers to keep themselves compliant.

Share this post


Link to post
Share on other sites
From a design point of view, why does a button need to point to "some memory location" that it modifies at all? What would it be supposed to do with the void* anyway, if it doesn't know what it points to and what it is used for? It can neither do a meaningful operation on the value, nor do any meaningful consistency checks.

A button in its basic form sends a single event in reaction to the user doing a single thing. It doesn't know and should not know what value might be changed somewhere else. A more advanced button will maybe send additional events for mouse over and whatnot... but it still does not know about anything outside its little box.

Some other piece of the application receives the generated event (via a callback or a message queue, or a socket, or whatever mechanism you like... a pigeon if you want), and that piece of code reacts to the event. It knows what value is to be changed in response (if there is one), and it knows its type.

Share this post


Link to post
Share on other sites
Red Ant    471
[quote name='Kyall' timestamp='1331263635' post='4920568']
I'm sorry that that's the way you'll have to define a template class, but take it up with those pricks on the c++ standards board who decided to make the export keyword a blank reserved keyword than to have to do any work whatsoever on their compilers to keep themselves compliant.
[/quote]

Well, if you want to keep the implementation separate from the interface you could still do it like this:

[code]
// in MenuButton.h
#ifndef MenuButton_h
#define MenuButton_h

class MenuItemBase
{
public:
virtual void MyFunc(int&) = 0;
};

template <typename T> class MenuButton : public MenuItemBase
{
public:
virtual void MyFunc( int& x );
};

#include "MenuButton.hpp"

#endif


// in MenuButton.hpp
template <typename T> void MenuButton<T>::MyFunc(int& x)
{
x = 5;
}
[/code]

Share this post


Link to post
Share on other sites
BennettSteele    493
Well, im pretty good with not leaving behind errors, and i have gotten it to work perfectly. i like all the ideas, but a void* pointer would be the easiest solution. although some may say its bad practice, it only is if you dont use it right. thanks for the ideas. :P

Share this post


Link to post
Share on other sites
mrbastard    1577
Easiest now, sure. But I'd argue that's only because you don't fully understand the other options. Type-safety is a very very valuable thing, and throwing it away shouldn't be taken lightly. That said, this is perhaps one of those things where you can't understand why it's so important until it affects you personally - when it bites you in a few years time, you'll understand [img]http://public.gamedev.net//public/style_emoticons/default/wink.png[/img] So it may be more valuable to you to make the mistake now so you can learn from it later. Or you may be absolutely right - you know your situation better than we do!

Anyway, I have another suggestion to add to the (very good) advice above. I think I'd go with each button holding an std::function<void(void)>, and use lambda capture to automagically get references to the needed variables. This is because I suspect that you don't actually want to say to a button "here, set this variable when you're clicked" - it would be far more useful to you to be able to say to a button "here's an arbitrary bit of code - run it when you get clicked".

[code]#include <functional>
#include <assert.h>
struct MyButton
{
void SetOnClickHandler(std::function<void(void)> handler)
{
onClickHandler = handler;
}
void OnClick()
{
if( onClickHandler )
{
onClickHandler();
}
}
std::function<void (void)> onClickHandler;
};
struct SomeGameLogicClassOrOther
{
void setupButton(MyButton& button)
{
auto myFunc = [&]()
{
//note m_buttonHasBeenClicked has been captured by reference
//=> you could capture other stuff by reference here too
//or just call a method on the SomeGameLogicClassOrOther
//which would allow you to do some checks or more complex logic
// - as Samoth pointed out would be useful
m_buttonHasBeenClicked = true;
};
button.SetOnClickHandler( myFunc );
}
bool m_buttonHasBeenClicked;
};
int main(int argc, char* argv[])
{
SomeGameLogicClassOrOther logic;
MyButton button;
logic.setupButton(button);

button.OnClick();
assert(logic.m_buttonHasBeenClicked);
return 0;
}[/code]

std::function and lambda are really nice tools for doing this sort of thing in a generic yet type-safe way.

Edit: unless you don't need to change the behaviour of a button instance at run time, in which case I'd go for the template option. [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]

Share this post


Link to post
Share on other sites
kunos    2254
[quote name='bennettbugs' timestamp='1331360065' post='4920841']
Well, im pretty good with not leaving behind errors, and i have gotten it to work perfectly. i like all the ideas, but a void* pointer would be the easiest solution. although some may say its bad practice, it only is if you dont use it right. thanks for the ideas. [img]http://public.gamedev.net//public/style_emoticons/default/tongue.png[/img]
[/quote]

sadly you just missed a chance to learn something that will make you a better programmer in the long run and the entire point of C++.
If this is a paid gig then fine, you got it working and you'll get paid. If this is something you do to learn, you did just learn the wrong thing.

Stoustrup.. the author of C++ calls "dangerous" programmers with obsolete programming practices "void* guys" .. you do the math ;)

Share this post


Link to post
Share on other sites
Kyall    287
Man, I can be so much more dangerous than a void* guy. But I won't act so dangerously for production code. Trying to debug something, then it's okay just cause it minimises the amount of code you need to write to work out wtf is up with a system.

Funnily enough void* and other dangerous sorts of programming are pretty much what leads to the types of errors I've found in the past that I had to do dangerous programming to debug...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this