Просто проверьте размер значения внутри макроса:
#define OSAtomicCompareAndSwap(old, new, mem) do{ \
if (sizeof(*old) == sizeof(int32_t)) { \
OSAtomicCompareAndSwap32((int32_t)(*old), (int32_t) (new), (volatile int32_t *) (mem)); \
} else if (sizeof(*old) == sizeof(int64_t)) { \
OSAtomicCompareAndSwap64((int64_t)(*old), (int64_t) (new), (volatile int64_t *) (mem)); \
} else assert(0); }while(0)
Все равно проверки должны быть оптимизированы компилятором. Это не проверка типов (для этого нам понадобится C ++ - ish typeid), проверяется только размер.
Если вам нужно вернуть значение, если вам нужно передать другую переменную:
#define OSAtomicCompareAndSwap(ret, old, new, mem) do{ \
if (sizeof(*old) == sizeof(int32_t)) { \
ret = OSAtomicCompareAndSwap32((int32_t)(*old), (int32_t) (new), (volatile int32_t *) (mem)); \
} else if (sizeof(*old) == sizeof(int64_t)) { \
ret = OSAtomicCompareAndSwap64((int64_t)(*old), (int64_t) (new), (volatile int64_t *) (mem)); \
} else assert(0); }while(0)
или отл. передать указатель на переменную, которая будет связана с результатом или чем-то подобным. Или вы можете использовать выражение выражения расширение gcc.
С выражением оператора, которое может выглядеть следующим образом:
#define OSAtomicCompareAndSwap(old, new, mem) __extension__({ \
int64_t ret = 0; \
if (sizeof(*old) == sizeof(int32_t)) { \
ret = OSAtomicCompareAndSwap32((int32_t)(*old), (int32_t) (new), (volatile int32_t *) (mem)); \
} else if (sizeof(*old) == sizeof(int64_t)) { \
ret = OSAtomicCompareAndSwap64((int64_t)(*old), (int64_t) (new), (volatile int64_t *) (mem)); \
} else { \
assert(0); \
} \
ret; \
})