Page 95 - C-Language
P. 95
}
In this code, the macro will be expanded to ((a++) <= (10) ? (a++) : (10)). Since a++ (0) is smaller
than 10, a++ will be evaluated twice and it will make the value of a and what is returned from MIN
differ from you may expect.
This can be avoided by using functions, but note that the types will be fixed by the function
definition, whereas macros can be (too) flexible with types.
#include <stdio.h>
int min(int x, int y) {
return x <= y ? x : y;
}
int main(void) {
int a = 0;
printf("%d\n", min(a++, 10));
printf("a = %d\n", a);
return 0;
}
Now the problem of double-evaluation is fixed, but this min function cannot deal with double data
without truncating, for example.
Macro directives can be of two types:
#define OBJECT_LIKE_MACRO followed by a "replacement list" of preprocessor tokens
#define FUNCTION_LIKE_MACRO(with, arguments) followed by a replacement list
What distinguishes these two types of macros is the character that follows the identifier after
#define: if it's an lparen, it is a function-like macro; otherwise, it's an object-like macro. If the
intention is to write a function-like macro, there must not be any white space between the end of
the name of the macro and (. Check this for a detailed explanation.
C99
In C99 or later, you could use static inline int min(int x, int y) { … }.
C11
In C11, you could write a 'type-generic' expression for min.
#include <stdio.h>
#define min(x, y) _Generic((x), \
long double: min_ld, \
unsigned long long: min_ull, \
default: min_i \
)(x, y)
#define gen_min(suffix, type) \
static inline type min_##suffix(type x, type y) { return (x < y) ? x : y; }
https://riptutorial.com/ 71

