Fabricio
Fabricio

Reputation: 7925

Is it possible to check if a variable is of type struct?

Suppose I have the following structs:

struct A{
    int a;
} a;

struct B{
    A a;
    int b;
} b;

how to check if b is of type B or if b is of the type A?

Upvotes: 4

Views: 6680

Answers (6)

Nathan Moinvaziri
Nathan Moinvaziri

Reputation: 5638

If you are going to write your own type checking mechanism I recommend writing macros to fill in the type field for you.

typedef struct A {
   void *type;
   int a; 
} A;

This macro initializes each structure with it's type information using stringification:

 #define InitializeType(ptr, type) \
      ((ptr)->type == (void *)(#type ## __FILE__ ##))
 #define IsType(ptr, type)      \
      ((ptr)!=NULL && (ptr)->type != (void *)(#type ## __FILE__ ##))

It fills in the type field with a string containing the name of the struct and the file it is located in. You can have two structs with the same name across multiple source files, however you can't have two structs with the same name in the same source file, thus the reason for including the name of the source file that the type was initialized in. You would then use them like so:

 A alpha;
 InitializeType(&alpha, A);
 IsType(&alpha, A);

There are a couple of cavets though; you have to use string pooling compiler flag, you have to encapsulate your structs in "classes" so that type checking and initializing is localized to the source file that contains the private struct, and you have to have void *type as the first parameter in each struct.

Upvotes: 1

ouah
ouah

Reputation: 145829

At compile time:

#define WARN_IF_DIFFERENT_STRUCT_TYPE_1(T, o) do { \
    T temp = (o);                                  \
    (void) temp;                                   \
} while (0)

example:

struct B b;
/* will warn if b is not of struct A type */
WARN_IF_DIFFERENT_STRUCT_TYPE_1(struct A, b);  

With two objects passed as macro parameters using typeof GNU extension:

#define WARN_IF_DIFFERENT_STRUCT_TYPE_2(o1, o2) do { \
    typeof(o1) temp = (o2);                          \
    (void) temp;                                     \
} while (0)   

example:

struct A a;
struct B b;
/* will warn if a and b are not the same struct type */
WARN_IF_DIFFERENT_STRUCT_TYPE_2(a, b);  

Upvotes: 3

Unsigned
Unsigned

Reputation: 9916

No. Unlike C++, which uses a vtable to maintain type associations at runtime, C provides no method for runtime type-checking.

A possible workaround would be to assign a type identifer as the first element of the struct:

struct A {
    int type;
    int a;
} a; a.type = 'A';

struct B {
    int type;
    A a;
    int b;
} b; b.type = 'B';

// Now, given a (void*) pointer `ptr`, of either `A` or `B`...
if ( *(int*)ptr == 'A')
{
    // ...
}
elseif ( *(int*)ptr == 'B')
{
    // ...
}

Upvotes: 0

Florin Stingaciu
Florin Stingaciu

Reputation: 8275

You could hack it? If really neccessary and you only have a couple structs.

struct A{
    int a;
    int identifer = 0;
} a;

struct B{
    A a;
    int b;
    int identifer = 1;
} b;

And if your code you can be like

if object->identifer == 0 
     bla bla bla

Upvotes: -2

tskuzzy
tskuzzy

Reputation: 36446

No as far as C is concerned, data is just a string of bits. How you use and interpret the data is up to the programmer.

It's just like how a char can represent a character, a positive number or a negative number (or anything else for that matter). It depends on the context and how it's used by the programmer.

Upvotes: 0

Ernest Friedman-Hill
Ernest Friedman-Hill

Reputation: 81684

Do you mean at runtime, given a void * that points to one or the other? Unfortunately, this is not possible; C doesn't have any kind of runtime type information mechanism.

Upvotes: 12

Related Questions