Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Portable way to "unpoint" a pointer typedef?

Tags:

c

typeof

typedef

This is unfortunately defined in some external library: cannot touch!

// library.h
typedef struct {
    long foo;
    char *bar;
   /* ... (long & complex stuff omitted) */
} *pointer_to_complex_struct_t;

Now The Question: how to declare an complex_struct_t variable?

  • Ideal solution but not allowed! (cannot change external library):

    // library.h
      /* ... (long & complex stuff omitted) */
    } complex_struct_t, *pointer_to_complex_struct_t;
    
    
    // my.h
    extern complex_struct_t my_variable;
    
  • Non-portable solution (gcc):

    // my.h
    extern typeof( * (type_placeholder)0 )  my_variable; // Thanks caf!
    
  • Other? Better? Thanks!

Bonus question: same question for a function pointer (in case there is any difference; I doubt it).


ADDED bonus: below is the exact same question but with functions instead of structs. This should not make any difference to the short answer ("No."), the only answer I was initially interested in. I did not expect some people to die trying to know and get my job done with creative workarounds, which is why I simplified the question from functions to structs (function pointers have special implicit conversion rules for convenience and confusion). But hey, why not? Let's get the copy-paste workaround competition started. Some workarounds are probably better than others.

///// library.h //////
// Signature has been simplified
typedef double (*ptr_to_callback_t)(long, int, char *);
// Too bad this is not provided: typedef double callback_t(long, int, char *);

///// my.h /////
// This avoids copy-paste but is not portable
typedef typeof( * (ptr_to_callback_t)0 ) callback_t;

extern callback_t callback_1;
extern callback_t callback_2;
extern callback_t callback_3;
// etc.

Short answer = no, there is currently no portable alternative to typeof

A basic copy-paste workaround works OK for functions but not for structs. The compiler will match the duplicated function types, but will not relate the duplicated struct types: a cast is required and the duplicated struct types will diverge without compilation warning.

like image 782
MarcH Avatar asked Oct 15 '25 21:10

MarcH


1 Answers

No, unfortunately you cannot do it with standard C. With C++ a simple metafunction would do the trick though.

However you could just copy-paste the definition of the struct thus leaving the original untouched

typedef struct {
 ///same  struct
} complex_struct_t;

The downside of this solution is that the expression &complex_struct_t won't be of type pointer_to_complex_struct_t, instead it will be of type pointer to unnamed struct {//your members}; You'll need reinterpret_casting, if you need that feature...

like image 137
Armen Tsirunyan Avatar answered Oct 18 '25 11:10

Armen Tsirunyan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!