0

I try to write a function, that finds void pointers in a data structure. The function has to cast the void* to any kind of struct.

Let's say I write a struct, which I store in my data sturcture in form of a void pointer. Then I calls the function, which prints information of all stored data elements. To do that the function has to know to which type it should cast.

So my question is: Is it possible to give the function the informations it needs in form of a parameter somehow?

example code:

typedef struct{
    int a, b
} teststruct;


void DSOut(datastructure* ds, datatypeinfo dt){
    //...
    //search for data in ds
    //...
    //if data is found cast it to the type defined in dt
    //and print out the a and b fields
}


int main(){
    datastructure* ds = DSCreate(4, 3);  //can hold any type of data,
                                         //but should hold just one at a time
                                         //4 and 3 are just example parameters
    teststruct ts;
    ts.a = 4;
    ts.b = 10;

    teststruct ts2;
    ts2.a = 6;
    ts2.b = 12;

    //Add the teststructs to the data-structure
    DSAdd(2, 2, ts);     //the numbers are just for example
    DSAdd(4, 1, ts2);


    datatypeinfo  dt = teststruct;   //stores the type teststruct for DSOut
    DSOut(ds, dt);   //function, that prints information of all added teststructs

    return 0;
}

in this example DSOut(x,y) should print the following:

- on position 2, 2 is an element which holds following data: 4, 10.
- on position 4, 1 is an element which holds following data: 6, 12.

Do you think this is possible ?

bakkaa
  • 673
  • 6
  • 25
  • This is one of the problems with using `void` pointers - you lose all information about the type of the data to which the pointer points. – SevenBits Dec 27 '14 at 17:40
  • 1
    C doesn't have any way to do dynamic type declarations, all types have to be specified statically. The best you can do is a fixed list of data types, which you can process using `if/then/else` or `switch`. – Barmar Dec 27 '14 at 17:42
  • See http://stackoverflow.com/questions/18577404/how-can-a-mixed-data-type-int-float-char-etc-be-stored-in-an-array/18577481#18577481 for an example of what I'm talking about. – Barmar Dec 27 '14 at 17:43

2 Answers2

1

Types cannot be passed as parameters in C, so the short answer to your question is "no, it cannot be done", at least not in the general case. You could pass something that would allow you to identify one of a limited set of types, and then hard-code how to handle each of those types (I'm thinking of a big switch statement). Since you don't specify what datatypeinfo looks like, it isn't clear how general you expect it to be.

Scott Hunter
  • 48,888
  • 12
  • 60
  • 101
  • I wanted it to work for every possible type. But it's Ok that it is not possible. I found a better way to do what I want. – bakkaa Jan 09 '15 at 16:19
1

I can think of adding a type identifier field to your struct and check it's value to decide how to print it, and initialize the structs with functions to take care of the type field

enum Types {
    Point3D,
    Point2D
};

struct Base {
    enum Types type;
};

struct Point3D {
    enum Types type;
    int x;
    int y;
    int z;
};

struct Point2D {
    enum Types type;
    int u;
    int v;
};

void print(void *data)
{
    switch (((struct Base *)data)->type)
    {
    case Point2D:
        {
            struct Point2D *point;

            point = (struct Point2D *)data;
            printf("2D: %d, %d\n", point->u, point->v);
        }
        break;
    case Point3D:
        {
            struct Point3D *point;

            point = (struct Point3D *)data;
            printf("3D: %d, %d, %d\n", point->x, point->y, point->z);
        }
        break;
    }
}

void initialized2dPoint(struct Point2D *const point, int u, int v)
{
    if (point == NULL)
        return;
    point->type = Point2D;

    point->u = u;
    point->v = v;
}

void initialized3dPoint(struct Point3D *const point, int x, int y, int z)
{
    if (point == NULL)
        return;
    point->type = Point3D;

    point->x = x;
    point->y = y;
    point->z = z;
}

int main(void)
{
    struct Point2D point2d;
    struct Point3D point3d;

    initialized2dPoint(&point2d, 1, 2);
    initialized3dPoint(&point3d, 3, 4, 5);

    print(&point2d);
    print(&point3d);

    return 0;
}
Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97