tags:

views:

122

answers:

4

How do I write a macro CHECK(a, b) that generates compilation error when the two pointers a & b have different base type.

CHECK((int*)0, (char*)0) -> compilation error
CHECK((int*)0, (int*)0) -> works

I'm looking for some C89 code, but C99 + gcc extensions will also do.

A: 

I don't know how to do it using macros. If you can use C++, then take a look here

Naveen
A: 

You can try this way:

#define CHECK(A,B) do { typeof(*A) _A; typeof(*B) _B; _A = _B; } while (0)

If your base types and not integer types (char, int, short, long, long long), types will not be promoted so assignment _A = _B will fail.

I don't think there is a way to make it working for integer types.

qrdl
A: 

So, unfortunately I don't know my standards very well. But you can do it like this

template <typename T>
inline void Checker(T*, T*) {}

#define CHECK(a, b) (Checker(a,b))

That will fail to compile for any types which are different.

ETA: Obviously only if you're in C++ mode. Apologies if you aren't

Salgar
+4  A: 

EDIT now works for any type, not just pointers

Something more or less lifted from the linux kernel, using the GCC extension typeof().

This generates a warning at compile time, it also works for integer pointer types

#define CHECK(a, b) do { \
    typeof(a) _a; \
    typeof(b) _b; \
    (void) (&_a == &_b); \
    } while (0)

int main(int argc, char **argv)
{
    int *foo;
    int *bar;
    char *baz;

    CHECK(foo, bar);
    CHECK(bar, baz);
    return 0;
}
Hasturkun
It won't work for pointers to integer types - compiler will promote smaller type to bigger one and no error will occur
qrdl
have you tried it?for this program gcc outputs the following: `a.c:16: warning: comparison of distinct pointer types lacks a cast`I always compile with the `-Werror` flag, btw.
Hasturkun
Anyway, pointer types do not get promoted, that would make very little sense. their dereferenced contents might, but they aren't being examined here.
Hasturkun