• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 190
  • Last Modified:

code to test what kind of variable is being passed

I have a function that is passing a void *

I would like to know if there is a way to test what kind of variable it is. So need to know how to write a function that analyzed the value of the (void *) and decides whether its an int, char, long, struct.

for example


int test_function(void *value){
int var_type = 0;
var_type = checktype(value);

if(var_type == INT)
/*cast value to an integer*/

...
0
pesst
Asked:
pesst
  • 6
  • 3
  • 3
  • +7
1 Solution
 
KurtVonCommented:
What's the difference between an int* a char* and a long*?  When all you have is the pointer, the answer is nothing.

Sorry, there is no way to tell.

Theoretically, if void* is being used, there is a way to know what it is based on what you passed in the first place, but that depends on the specifics, which you didn't provide.
0
 
peepzCommented:
the point of a void * is to make the variable amenable to typecasting to a favorable type.If all you want to check is the type passed why do you want to even pass it as void.Instead catch it at the source.
0
 
grg99Commented:
No real way to tell, that's one of  the beauties of C.  :(


One way, which requires a bit of work, is to declare all your pointer-based data with the first field being an enum or similar field that describes what follows.



0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
raphaelbCommented:
There is a way but with some coding overhead...  Use virtual funtions with wrapper classes for builtin types.  I havn't coded in C++ for a while and I got nothing to check syntax so it might be a little bit off but here goes.

class Types {
virtual int returntype();
};

class Integer: public Types {
public:
int value;
int returntype() {return 1;  // 1 for int};
};

class Character: public Types {
public:
char value;
int returntype() {return 2; // 2 for char);
};

void main()
{
   Integer i;
   i.value = 5;
   testfunction(&i);
}

int testfunction(void *foo) { // could use (Types *) instead of void* here

Types t = (Types)*foo;
int var_type = t.returntype();

if (var_type == 1)
    int i = t.value;
    // it's an int

if (var_type == 2)
    char c = t.value;
    // it's a char
}

Now I am by no means a expert c++ programmer, so there might be an easier way of doing this through runtime type info that I am not aware of..  

Raphael
0
 
raphaelbCommented:
Forgot to say, this will only work for C++;
0
 
wide_awakeCommented:
If you're able to re-work the code that provides the void* in the first place, then you could add a parameter to the function that indicates the type of the void*.

That way, you can still have a "generic" function that works on any void*, but you can also tell what the type of the void* is supposed to be.
0
 
fridomCommented:
C does not provide facilities for that but of course you can help yourself how that is done can be studied in glib or GTK+

Ther is too an online book available seach for ooc.pdf or ooc.ps.

Base idea is of course using a struct.

struct Object {
    void * Super;
    // pointer to functions on Object
    // maybe some data
    int type_tag;
}

you than write sort of Konstructors in which you initialize the values with the proper fields. Again check out GTK+ on how that might look

Regards
Friedrich
   
0
 
Mayank SAssociate Director - Product EngineeringCommented:
Maybe something like:

int type ( void * ptr )
{
  int size = sizeof ( * ptr ) ;

  if ( size == sizeof ( int ) )
    return 1 ; // for integer

  else if ( size == sizeof ( float ) )
    return 2 ; // for float

.... // and so on
....

} // end of type ()


Mayank.
0
 
pesstAuthor Commented:
Ok, I see the problem for int, char, float ...

So the most common use of passing a void * for passing different structures? And usually defined in the structure is tag that describes what it contains?

0
 
KurtVonCommented:
Usually it is used to pass data to a callback.  Since the person calling the function calling the callback knows what the void* is pointing to, it is easy for them to cast it back in the callback:

bool Callback(void* ptr)
{
    IMPORTANT_DATA* data = (IMPORTANT_DATA*)ptr;
    // Use data to figure out what to resturn
}

void LaunchCallback()
{
    IMPORTANT_DATA data;

    SomeFunctionWithCallback(Callback, (void*)&data)
}

See, this way the callback function can use any struct or object or even a pointer to a primitive, and the function SomeFunctionWithCallback doesn't need to even know what the data is to pass it on.
0
 
gj62Commented:
Mayank,

That absolutely WILL NOT work.

sizeof(*ptr) is calculated at COMPILE time, not runtime.  

The compiler should give you an error regarding illegal indirection...
0
 
Mayank SAssociate Director - Product EngineeringCommented:
I thought so, that's why I said 'maybe'. Surprisingly, on my Turbo compiler, it doesn't give an error during compiling but gives during execution!

Mayank.
0
 
gj62Commented:
Mayank, neither does gcc - it even runs with no errors, but always returns 1...  Visual C gives illegal indirection...

However, it can't give us what we are looking for.  As I said, sizeof() is evaluated at compile-time...

0
 
Mayank SAssociate Director - Product EngineeringCommented:
This one says 'Abnormal Program Termination' :-()

Mayank.
0
 
gj62Commented:
That's odd.  The expression should end up in the runtime code as

size=1

or some such...  I wonder what your compiler is actually generating...

Are you sure it's crashing there?
0
 
svatOplukCommented:
You cant know what is void * pointing to. Casting it lets say to int * and dereferencing it data is converted to int  even though the original data could have been anything else.
0
 
gj62Commented:
svatOpluk,

Correct - as we've all said.  

However, if you were replying to the problem that Mayank was having with his program crashing, he was merely taking sizeof(*ptr), which is a compile-time process and not a dereference, and therefor should not create code that crashes during runtime.  
0
 
KurtVonCommented:
Perhpas his compiler uses sizeof(void)==0.  I don't think there is an ANSI standard answer for it.  If 0 was not a choice taken into account, it could be falling through all the tests and crashing for lack of a return value (though the compiler should catch that).
0
 
gj62Commented:
Yeah - my question is just that since it is a compile-time conversion, and it *should* resolve to an integer (even if -1!), unless he gets a compiler warning that not all control paths return correctly, I can't imagine it crashing.

Oh well, it was more of a "just wondering" question - maybe I'll download the Borland compiler and look at the assembly it creates...
0
 
pesstAuthor Commented:
Ok, so who wants the points. I think its agreed that the answer is NO. KurtVon said NO first I think he gets the points. Any objections?
0
 
gj62Commented:
KurtVon should get the points...  

The rest of us just have nothing better to do than start discussion threads on minute details after the answer has already been given... <grin>

pesst - thank you for asking, that's a nice thing to do...
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

  • 6
  • 3
  • 3
  • +7
Tackle projects and never again get stuck behind a technical roadblock.
Join Now