Checking if a type is a struct or pointer at compile time in C?

為{幸葍}努か 提交于 2019-12-22 13:53:51

问题


NOTE: This is NOT a duplicate of the question linked by Paul T, because I am asking if it is possible to determine if a type is of a certain broader incomplete type/kind at compile time, not if a symbol has been registered at compile time. This seems like a fundamental misunderstanding of the question.

I am writing a library in C that deals with pseudo-generic functions which take a type as an argument through a macro wrapper.

To spare the details (because they are rather complicated) there are two possible features that could help, I think:

  • Being able to detect if a type is a pointer at compile time. (No, the "use _Generic to test if you get ptrdiff_t from subtraction" trick won't work, because structures are a possibility, and you can't subtract structures.)

  • Being able to detect if a type is a struct at compile time. (If this was possible, then the aforementioned _Generic trick could be used if the type was detected as not being a struct.)

I've tried everything I could think of on Godbolt (even trying to compare types to incomplete anonymous structs and toying with __builtin_types_compatible_p) and wasn't able to find any solutions.

If anyone has any solutions I'd love to see them, otherwise I may just end up having to complicate the design a bit-- so not the end of the world if it's impossible, but it would be ideal if it can be done.

To give a basic idea of what one of these macros might look like or their expected output:

int *a;
assert(!IS_STRUCT(a));
assert(IS_POINTER(a));
struct {} b;
assert(IS_STRUCT(b));
assert(!IS_POINTER(b));

shouldn't throw any errors.


回答1:


Complete Answer (if EDG Front End used):

If your IDE / compiler is using the EDG C++ Front End (which a lot are), and you are using C, not C++ (which your tag suggests), and you say you ARE using typeof, then you can detect a structs as follows (see the latest manual, page 75):

/* Test if EDG Front End is used*/
#if defined(__EDG__) && defined(__EDG_VERSION__)
#define IS_STRUCT(expression_or_type_name) __is_class(typeof (expression_or_type_name)))
#endif

since in C __is_class() will only be true for a struct (http://www.cplusplus.com/reference/type_traits/is_class/).

Further, pointers can similarly be detected as follows:

/* Test if EDG Front End is used*/
#if defined(__EDG__) && defined(__EDG_VERSION__)
#define IS_POINTER(expression_or_type_name) (__is_convertible_to(typeof (expression_or_type_name), void*) || __is_convertible_to(typeof (expression_or_type_name), void const*) || __is_convertible_to(typeof (expression_or_type_name), void volatile*) || __is_convertible_to(typeof (expression_or_type_name), void const volatile*))
#endif

(http://www.cplusplus.com/reference/type_traits/is_convertible/)




回答2:


  1. It’s not possible in standard C. Whatever solutions there may be must be implementation-defined.

  2. It seems that C is not a suitable language for your problem domain. Short of esoteric platforms that come without C++ support, there seems to be little reason to have to solve this in C. On most any platform where C is available, so is C++. Since you claim that you use gcc, then C++ is surely available and you can process some of the input using a C++ compiler. You could do the input processing as a generator step: run the code through a C++ compiler to generate source code that defines constants that capture type properties sought.



来源:https://stackoverflow.com/questions/54452381/checking-if-a-type-is-a-struct-or-pointer-at-compile-time-in-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!