Say a function takes a void pointer as an argument, like so: int func(void *p);
How can we determine or guess the type of what p is pointing to?

- 14,179
- 14
- 48
- 71
4 Answers
In general, you can't. In some cases, if there is a guarantee on what p points to, you may be able to look at the contents at and after that address to find out. Generally, your function should know what it's being passed, unless it just passes it along.
Data and function arguments in C are just a bunch of bits lumped together. Unless you use some of those bits to tell you what the bits are, there's no consistent way to identify it.

- 13,974
- 3
- 42
- 42
-
6Voting this up... you know because you have made sure of the types in the rest of your program. If that sounds fragile it is because it is fragile. Welcome to C. Use a less fragile system where you can. – Tagore Smith Apr 09 '10 at 03:03
-
I remember some Motif (of all things) code awhile back where you would get a pointer in, and you would look at the first bytes after the pointer to determine what the type was, and then you deal with that type appropriately. What a mess. – WhirlWind Apr 09 '10 at 03:05
-
I won't be doing this in practice. I was just curious of ways that this can be done. Also, A GNU C extension provides the typeof() operator which (I think) will be able to determine the type of what's dereferenced (i.e. typeof(*p)), but I haven't used it yet. – Yktula Apr 09 '10 at 03:09
-
2I'd guess typeof will tell you "void," since there's no way for the compiler to know at compile time. – WhirlWind Apr 09 '10 at 03:12
-
2there's no way typeof() can reliably infer the type of a void*. it might be able to do something, if that pointer points to an object that was allocated by the heap-allocator used by the standard memory allocation library used by the compiler; however, if that pointer points to an object that is allocated by a custom heap allocator (your own new operator) or was allocated by OS API (OLE SAFEARRAY) or by code in a different language (a VB5 COM component or POCO object exposed through managed C++), it's impossible to do anything. – Franci Penov Apr 09 '10 at 03:27
-
1@WhirlWind, 255 possible types sounds very limited though :P @Yktula, RTTI, or more precisely, the typeid operator, doesn't query the type_info hierarchy for void pointers because they have none. So it can't guess what type it points to. – jweyrich Apr 09 '10 at 03:36
-
1`typeof` only tells you the static/compile-time type. So if you have `void *p`, `typeof(*p)` -> `void`. – R Samuel Klatchko Apr 09 '10 at 04:32
Sure you can, and it's easy too. It's C, do whatever you want, how you want it.
Make a type system. Put everything you pass into a structure, make the first byte or two a magic number to determine what the structure contains beyond the magic number.
Make some functions to create/get/set/destroy the "typed variables".
Make some other functions to add and register new types at runtime.
Create a few defines to make it easier to read and typecast the structs.
Before you know it you will have a nice proprietary type system you can use for your projects, and it will always do EXACTLY what you want and need because YOU made it.
You could go crazy and grow it into a full object oriented like system. Or save yourself the work, and use the work of all the other people who already went crazy - http://en.wikipedia.org/wiki/GObject

- 81
- 1
-
So, how does this work when the function you write is called from code you don't control? – WhirlWind Apr 09 '10 at 03:53
-
2If the function is being called from code you don't control, then you are making the API/Library, so you have to document the interface, and the functions to create/get/set/destroy the typed variables. If for some reason the callee is the one in control, and they don't want/refuse to use your custom 'typed' system, then you're out of luck. You have to let them decide how they are going to pass you typed information, and code to that. – Antebellum Jun 29 '11 at 03:05
Short answer - you cannot.
In C there's no runtime time information unless you provide it, but look at the printf(3)
family and see how easy it is to shoot yourself in the foot with mismatched format spec and actual argument type.
Type system is your friend. Use it.

- 82,306
- 11
- 110
- 171
I was confronted with a similar problem and I found myself having to write an instruction set for a programming language project. I came up against this problem because I had an array of pointers to functions so that functions could be enumerated and run in a for loop (for things like online help and syntax etc). For example:
struct List_Str *(*InstructionSet[])(struct List_Str *ContextPrefix,struct List_Str *ContextSuffix)=
{
AAVF,Add,AddEmotions,AddEmoDebug,AddScope,...
};
Now you could easily do the same thing with char * instead of struct List_Str * types, then convert all data into string format using snprintf and atoi and atof and other conversion functions. If you do a:
man isalpha
This shows you lots of functions in ctype.h that could give you ideas how to determine what type of data is held within the strings.
Folding all types into "stringy" format allows tremendous flexibility and regularity, but automagically converting the data from the strings to integers, floats etc, is arduous, but fruitful once the routines are librified.
If you intend to hold binary data, then you cannot use strings, since 0 chars can be inside the binary data and this confuses strlen functions. Furthermore, you have no idea of the length of what has been malloc'd once it leaves scope, so storing the length of the dereferenced data before the data is recommended in the first few bytes of char *.
One last thing, I wouldn't recommend storing data in void *, it's too vague. I recommend using char * as it's a bit more specific, can contain everything that void * can and the compiler will let you know beforehand if anything looks fishy.

- 1,755
- 2
- 24
- 34

- 1,446
- 14
- 20
-
2If you use `char*` as a generic data pointer, it's too easy IMHO to accidentally dereference the pointer without first converting to the proper type. – Keith Thompson May 23 '13 at 00:10