tags:

views:

1182

answers:

11

How do you check if a pointer is of a certain type?

Using sizeof is not sufficient.

I am trying to avoid putting id-numbers into my structs to identify their type. The assumption is that maybe gcc puts a struct definition somewhere in the process, and maps the definition to the allocated memory at a pointer. If this is true, I'd think there would be someway to check for a pointers type.

+31  A: 

You can't.

A pointer merely stores an address and nothing related to the contents of that address.

Mehrdad Afshari
Like Mehrdad said, C doesn't have ANY kind of runtime type information
wvdschel
+4  A: 

No, there's no runtime type information anywhere.

You should write your functions so that the function signature carries the type information and let the compiler check the types statically. For example void burp_foo(struct foo *thefoo) tells that the argument is a pointer to a struct foo. It is up to the caller to supply one. Of course, through type casting it is possible supply any pointer as pointing to a struct foo but then it's the caller's problem, not yours.

laalto
+2  A: 

You can't do that in C. Actually the C++ compiler does something like what you want (storing information about the type of a class to the allocated memory). In C you have no classes, but only structs, which contain no overheads whatsoever.

kgiannakakis
Even in C++ this is stored only for polymorphic classes (classes with virtual functions). In other cases compile time information needs to be used.
Suma
+1  A: 

There's nothing like this in C. A pointer is either of a specific type or it is void*. There's no function overloading or built-in runtime polymorphism like in C++. You can though do pseudo object oriented tricks using function pointers, like:


typedef void (*cmd_func)( int );
struct command
{
    int      arg;
    cmd_func action;
};
Nikolai N Fetissov
+6  A: 

Pointer is the type. More generally, C doesn't provide the ability to do introspection. There's no programmatic way to determine the type of a variable.

Michael Carman
to be correct there is no built-in language feature. You could roll your own RTTI if you want to. C has all you need for that.
Nils Pipenbrinck
what is a RTTI ?
LB
@Nils: That's why I said "C doesn't provide..." The OP was looking for something built-in.
Michael Carman
@LB: It's a C++ language feature to grab information about types at _runtime_. Something like reflection in .NET, albeit with much less features.
Mehrdad Afshari
RTTI: Run Time Type Information
Binary Worrier
Or Run-Time Type Identification. Not sure what the spec uses, but both are in common use now. Same idea.
Steve Fallows
+11  A: 

"I am trying to avoid putting idnumbers into my structs to identify their type." Don't avoid that. If you really want to be able to check type, put a typeID as the first element of every struct. Your impulse was not a bad one.

Nosredna
+2  A: 
andygavin
+1  A: 

May be You need Objective-C?

vitaly.v.ch
A: 

The C standard does not allow this directly. The C++ standard has some ability to do this (dynamic_cast and typeid).

typeof

GCC comes with a typeof operator that may be useful depending on what you're doing.

conditional operator

The conditional operator (the question mark and colon in expressions like x = y == 0 ? 1 : 0;) has some ability to tell you if two types can be coerced into a third type (that article is about C++, but the type safety of the conditional operator is the same in C). Its use is nonobvious to say the least.

Both of these techniques (typeof and the conditional operator) are limited to what information is available at compile time. That is, you can't pass a void* to a function and then use typeof to figure out the original type of the object the pointer points to inside that function (because such information isn't available inside that function at compile time).


Thinking more about this, GTK+ is written in C and has a system you may consider emulating. It looks like they use type IDs, but instead of putting the IDs in the struct, they use macros to look things up.

Max Lybbert
typeof is compile time, so does not solve the problem.
andygavin
+2  A: 

A way to avoid putting a ID member in your struct is to use polymorphism like :

typedef struct {
        char const *name;
        int id;
        /* ... */
} object_info_t;

typedef struct {
        object_info_t *info;
} object_t;

typedef struct {
        object_t object;
        int a;
} foo_t;

typedef struct {
        object_t object;
        int b;
} bar_t;

int object_get_id(object_t *object)
{
        return object->info->id;
}

Note you can augment object_info_t with function pointers and avoid checking ids altogether :

typedef struct {
        char const *name;
        int id;
        int (*do_something)(object_t *);
} object_info_t;

int object_do_something(object_t *self)
{
        return self->info->do_something(self);
}
You can call me Chuck
+3  A: 
SPWorley
Guile (the Scheme implementation) uses something like this ( http://www.gnu.org/software/guile/manual/html_node/Faster-Integers.html )
Max Lybbert
@max, great example! I think Emacs used to do it 15+ years ago too, and it was a huge pain to un-do when they needed to scale to modern memory sizes.
SPWorley