Мне нужно найти максимум и минимум произвольного выражения C, которое не имеет побочных эффектов. Следующие макросы работают на моей машине. Будут ли они работать на всех платформах? Если нет, могут ли они быть изменены для работы? Я собираюсь использовать их для реализации макросов типа SAFE_MUL(a,b)
вместо a*b
. SAFE_MUL
будет включать проверку на переполнение умножения.
РЕДАКТИРОВАТЬ: тип приводится в соответствии с предложением Стива.
#include <stdio.h>
#include <limits.h>
#define IS_SIGNED(exp) (((exp)*0-1) < 0)
#define TYPE_MAX_UNSIGNED(exp) ((exp)*0-1)
#define TYPE_MAX_SIGNED(exp) ( \
sizeof (exp) == sizeof (int) \
? \
INT_MAX \
: \
( \
sizeof (exp) == sizeof (long) \
? \
LONG_MAX \
: \
LLONG_MAX \
) \
)
#define TYPE_MAX(exp) ((unsigned long long)( \
IS_SIGNED (exp) \
? \
TYPE_MAX_SIGNED (exp) \
: \
TYPE_MAX_UNSIGNED (exp) \
))
#define TYPE_MIN_SIGNED(exp) ( \
sizeof (exp) == sizeof (int) \
? \
INT_MIN \
: \
( \
sizeof (exp) == sizeof (long) \
? \
LONG_MIN \
: \
LLONG_MIN \
) \
)
#define TYPE_MIN(exp) ((long long)( \
IS_SIGNED (exp) \
? \
TYPE_MIN_SIGNED (exp) \
: \
(exp)*0 \
))
int
main (void) {
printf ("TYPE_MAX (1 + 1) = %lld\n", TYPE_MAX (1 + 1));
printf ("TYPE_MAX (1 + 1L) = %lld\n", TYPE_MAX (1 + 1L));
printf ("TYPE_MAX (1 + 1LL) = %lld\n", TYPE_MAX (1 + 1LL));
printf ("TYPE_MAX (1 + 1U) = %llu\n", TYPE_MAX (1 + 1U));
printf ("TYPE_MAX (1 + 1UL) = %llu\n", TYPE_MAX (1 + 1UL));
printf ("TYPE_MAX (1 + 1ULL) = %llu\n", TYPE_MAX (1 + 1ULL));
printf ("TYPE_MIN (1 + 1) = %lld\n", TYPE_MIN (1 + 1));
printf ("TYPE_MIN (1 + 1L) = %lld\n", TYPE_MIN (1 + 1L));
printf ("TYPE_MIN (1 + 1LL) = %lld\n", TYPE_MIN (1 + 1LL));
printf ("TYPE_MIN (1 + 1U) = %llu\n", TYPE_MIN (1 + 1U));
printf ("TYPE_MIN (1 + 1UL) = %llu\n", TYPE_MIN (1 + 1UL));
printf ("TYPE_MIN (1 + 1ULL) = %llu\n", TYPE_MIN (1 + 1ULL));
return 0;
}