How to check structure type in C

I created a simple list structure in C that contains any data using the void * pointer, for example:

struct node
{
    void *the_data;
    node *next;
};

It works fine, but I have a list containing, for example, only struct_a in the list and only struct_b in another list. I need to check if the first element of the list has type struct_a or type struct_b in one if () question so that I know the data stored in this list. How to do it? Thanks

Edit:

I came up with a simple solution that is enough for the problem now, I don’t know if this is better:

struct node
{
    void *data;
    node *next;
}

And I added a “handle” to the node, which contains the address of the first node and type information:

struct list_desc
{
    node *list;
    short int type;
}

and I will use it with some macros like

#define __data_type1 10
#define __data_type2 20

so later I can compare like if (struct.type == __data_tipe1) etc.

+4
source
4

:

typedef enum tag_ElementType
{
    ElementA,
    ElementB
} en_ElementType;

typedef struct tag_Container
{
    en_ElementType ElementType;
    void *pData;
} st_Container;

:

typedef struct tag_node
{
    st_Container the_data;
    struct tag_node *next;
} st_node;
+1

C . . ( C99 C11):

() :

struct Node {
    enum {
        OBJ_TYPE_A,
        OBJ_TYPE_B
    } type;
    union {
        struct NodeA a;
        struct NodeB b;
    };    // anonymous, if a name is added, you have an additional field name
};

...

struct Node *node = ...;

if ( node->type == OBJ_TYPE_A ) {

    node->a.a_field = whatever;

...

, .


:

struct Node {
    enum {
        OBJ_TYPE_A,
        OBJ_TYPE_B
    } type;
    struct Node *next;
};

struct NodeA {
    struct Node;    // base class, first field!
    int a_field;
};

struct NodeB {
    struct Node;    // base class, first field!
    float b_field;
};

void take_node(struct Node *node)
    // takes a generic pointer to the base-class
{

    if ( node->type == OBJ_TYPE_A ) {
        struct NodeA *a_node = (NodeA)node;
        a_node->a_field = whatever;
    } else if ...

    ...

}

// until here that is normal C99

int main(void)
{
    struct NodeA anode = { .type = OBJ_TYPE_A, .a_field = 42 };
    struct NodeB bnode = { .type = OBJ_TYPE_B, .b_field = 4.2 };
    take_node((Node *)&anode);    // standard: inhibits type checking
    take_node(&anode);    // plan9-extension: no cast required
    take_node(&bnode);    // plan9-extension: no cast required
}

Pro ( ) . , ( : child1_1_1_ptr->child1_1.child1.base.base_field, child1_1_1_ptr->base_field).

take_node gcc C-extension -fplan9-extensions. , ( ). .

, . , , OOPL, ++, .

+4

C - . "" , . , .

The usual method is to make the first element of the set of structures indefigator. Either a number (possibly an index into an information type table), or something like the address of an information type structure. You can then assign a pointer to any of these structures and verify that the first field determines what to do with it.

+2
source

C does not contain the runtime information that the pointer points to. You can create a structure containing a type field and a union containing everything you want to keep.

enum node_type {
    NODE_TYPE_STRING,
    NODE_TYPE_INT,
    NODE_TYPE_DOUBLE,
    NODE_TYPE_OTHER_STRUCT
};

struct other_struct {
    // define some fields
};
struct node_data {
   enum node_type type;
   union {
       char *string;
       int i;
       double d;
       struct other_struct other;
    } data;
};
+2
source

Source: https://habr.com/ru/post/1599389/


All Articles