2

I need to detect by a macro at compile time if a struct has a member. I've tried offsetof(struct object, a_field) but it causes error to be issued at compilation about non existing field. Is there some other method to check if a C struct has a field?

I need this for a macro

MESSAGE(obj, method, ...) obj->method(obj, ##__VA_ARGS);

So that I could use it also on non virtual methods, like:

MESSAGE(obj, method, ...) method(obj, ##__VA_ARGS);

So in general to detect if there is method member and if so, call it as obj->member(obj, …) and as member(obj, …) otherwise.

psprint
  • 349
  • 1
  • 10
  • 1
    C doesn't generally provide introspection mechanisms like this. And even if it did, how would you use it? – Barmar Mar 07 '21 at 18:33
  • 6
    What is the *actual* problem you have? Why do you need to "detect" a structure member? If we know the underlying and actual problem then we can help you with that instead (also do some research about [the XY problem](https://en.wikipedia.org/wiki/XY_problem)). – Some programmer dude Mar 07 '21 at 18:33
  • @Someprogrammerdude: I've extended question. – psprint Mar 07 '21 at 18:40
  • "I need to detect by a macro at compile time if a struct has a member. " then later "it causes error to be issued at compilation about non existing field". To me that sounds like a success story. So what is your question? – Yunnosch Mar 07 '21 at 19:12
  • 1
    To me this has a smell of bad design. Or a bad implementation of a (possibly) good design. Either way, this can't be done using standard C, and trying to shoehorn it in using some kind of home-written preprocessor is only going to make the code complex, hard to read, understand and maintain. – Some programmer dude Mar 07 '21 at 19:40
  • Why not wrap a call to virtual method into a call of non virtual method. ' method(obj *x) { obj->method(obj); }' and use non-virtual variant everywhere. – tstanisl Mar 07 '21 at 20:34
  • @Yunnosch: question is: how to _gracefully_ detect a member, without compilation error. – psprint Mar 07 '21 at 21:56
  • @psprint You tagged this as C, but there are no "*methods*" in C, virtual or otherwise. If the question is about C++ instead then see for example [Templated check for the existence of a class member function?](https://stackoverflow.com/questions/257288/templated-check-for-the-existence-of-a-class-member-function). – dxiv Mar 07 '21 at 23:07
  • @dxiv: But yes there are! :) Inheritance – `struct Extended { BaseStruct base; /* … extension fields follow */ }`, virtual methods ↔ `extended->myfun(extended, …`, private functions ↔ `static int my_nonpublic_func(Extended *this)`, etc. I have been a C++ coder to now discover that you can do almost regular OOP in plain C :) And with `-fms-extensions` one can obtain a true inheritance. I hope that it will get to a C standard at some point. – psprint Mar 07 '21 at 23:25
  • @psprint Sure, you [can](https://stackoverflow.com/a/66084772/5538420) simulate all that in C, but calling it "*virtual methods*" without context or explanation will only invite confusion. – dxiv Mar 07 '21 at 23:56
  • @dxiv: ah I see what you mean, thanks for pointing it out. – psprint Mar 08 '21 at 00:27

1 Answers1

1

Types are known at compilation time. This means you cannot use a structure field which has not been declared in such a structure. You can use the field, and get an error from the compiler if the provider of such structure has not declared the field properly, but there's no way to check it conditionally.

Luis Colorado
  • 10,974
  • 1
  • 16
  • 31