3

What do I know is that C has _Generic macros. One can even implement some limited typename() for ANSI C (just like it is mentioned here).

But can I implement something like std::is_pointer in C? For example:

#define IS_POINTER_TYPE(x) // ?

struct Vec2 {
    float x;
    float y;
};

int main(int argc, char* argv[], char* env[])
{
    IS_POINTER_TYPE(Vec2*);     // true
    IS_POINTER_TYPE(int*)       // true
    IS_POINTER_TYPE(char)       // false
    IS_POINTER_TYPE(const int)  // false
}

Can I do this for variables, not types? Thank you.

UPD: This solution is not portable and not generic unfortunately. One require monkey-job copy-pasting or code generation to make all your structures conform to this notation. You guys guided me to a decision if you don't require 100% accuracy and can tolerate some false-positives.

Netherwire
  • 2,669
  • 3
  • 31
  • 54
  • 1
    See https://stackoverflow.com/questions/54452381/checking-if-a-type-is-a-struct-or-pointer-at-compile-time-in-c/54460700#54460700 for a discussion – Gunther Schulz Feb 12 '19 at 10:26
  • 2
    @KamilCuk That won't distinguish ptrs from structs/unions/enums/arrays. – Petr Skocik Feb 12 '19 at 10:29
  • Sidenote: Given how limited language C is, if you find yourself needing this feature often, you are not probably using right language for the job. – user694733 Feb 12 '19 at 10:41
  • 1
    @user694733 You can do a ton a ton of that zero-cost-abstraction high-meta stuff many people think you need C++ for with just C (especially if you include nonstandard but common extensions like `__typeof`, `({ })`, and `__label__`). Not all of it. This is one of those things that's missing from C. – Petr Skocik Feb 12 '19 at 11:42

1 Answers1

1

No unless you know what type of pointer it could be. I don't know of any nonstandard gcc/clang extension that can accomplish it either. The closest thing to it that you can do is a comptime assert that something is a pointer, e.g., with (void const*){TheThing} (will also accept zero literals as those can be used null pointers and arrays (you can use _Generic to weed those out)) or by applying a pointer op (*, [0]) to it while using _Generic with __typeof to weed out arrays.

Petr Skocik
  • 58,047
  • 6
  • 95
  • 142