I need to find the maximum and minimum of an arbitrary C expression that has no side effects. The following macros work on my machine. Will they work on all platforms? If not, can they be changed to work? I intend to use them to implement macros like SAFE_MUL(a,b) instead of a*b . SAFE_MUL will include overflow check.
EDIT: the type is cast as suggested by Steve.
#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; }
source share