Thread: Determine the type of a struct at runtime

  1. #1
    Registered User
    Join Date
    Oct 2019
    Posts
    82

    Determine the type of a struct at runtime

    Hello,

    My data is coming in the form of a pointer to void. My aim is to dump the data to stderr in a structured way. The data pointed to by the struct is a struct that could be of several types. In order to print this data out in a structured way, there is the need to determine its type.

    Code:
    static void dump(const char *prefix, size_t size)
    {
         //cur_data is a global variable, we wish to print out the struct pointed to by it
    }
    My first thought is that we can use sizeof such that, if the size of the global variable 'cur_data' equal the size of the a certain struct, then we can assume that the contents of the global variable is the said struct.

    Code:
    size_t struct_size = sizeof(*cur_data);
    
    switch(struct_size){
       
       case sizeof(struct A):
    
       case sizeof(struct B):
    
       case sizeof(struct C);
    
       default:
    
    }
    Could someone know of a better way to do this?

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    > cur_data is a global variable
    Ugh, why isn't it a parameter?

    Code:
    static void dump(void *cur_data, const char *prefix, size_t size)
    {
      switch(size){
        case sizeof(struct A): {
          struct A *p = cur_data;
          // do stuff with p->members
          break;
        }
     
        case sizeof(struct B):
     
        case sizeof(struct C);
     
        default:
      }
    }
    But this only works if all your structures have distinct sizes.

    Normally you would have a variant structure as follows.
    Code:
    struct all {
      int type;
      union {
        struct A a;
        struct B b;
        struct C c;
      }v;
    };
    Where the .type member specifically identifies which of A,B,C is the real data representation.

    You would then switch on .type in your generic handling.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Oct 2019
    Posts
    82
    Quote Originally Posted by Salem View Post
    > cur_data is a global variable
    Ugh, why isn't it a parameter?

    Code:
    static void dump(void *cur_data, const char *prefix, size_t size)
    {
      switch(size){
        case sizeof(struct A): {
          struct A *p = cur_data;
          // do stuff with p->members
          break;
        }
     
        case sizeof(struct B):
     
        case sizeof(struct C);
     
        default:
      }
    }
    But this only works if all your structures have distinct sizes.

    Normally you would have a variant structure as follows.
    Code:
    struct all {
      int type;
      union {
        struct A a;
        struct B b;
        struct C c;
      }v;
    };
    Where the .type member specifically identifies which of A,B,C is the real data representation.

    You would then switch on .type in your generic handling.
    Thanks for your input.

    Quote Originally Posted by Salem View Post
    > cur_data is a global variable
    Ugh, why isn't it a parameter?
    Good question

  4. #4
    Registered User
    Join Date
    Apr 2021
    Posts
    136
    Create an array of const char * pointers into a single string. Each pointer must be distinct, but the set of pointers must also be compact.

    Use the _Generic() feature, with a macro, to implement your "function".

    Have the _Generic feature match the type of the parameter, and pass the corresponding string literal, so that dump(&some_struct, ...) is remapped to dump(Array_of_literals[SOME_STRUCT_ID], &some_struct, ...)

    Map char * to self, NULL.

    Now inside your function, decode the first pointer. If the first pointer is pointing anywhere inside the compact string you created in step 1, then the pointer is a valid structure identifier and you can decode it to determine the size and how it should be dumped. If not, it is a char * string literal and you can expect NULL as the second parameter - just dump the string.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Determine file type (Linux)
    By cnewbie1 in forum C Programming
    Replies: 12
    Last Post: 12-29-2010, 01:24 PM
  2. how can determine the file encode type
    By firperfect in forum Linux Programming
    Replies: 1
    Last Post: 03-13-2008, 08:04 PM
  3. determine file type
    By zedoo in forum Linux Programming
    Replies: 1
    Last Post: 10-03-2005, 10:50 AM
  4. determine type of void
    By rotis23 in forum C Programming
    Replies: 5
    Last Post: 08-25-2004, 03:16 PM
  5. Determine type
    By Mithoric in forum Windows Programming
    Replies: 1
    Last Post: 04-12-2004, 10:27 PM

Tags for this Thread