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
   90   91   92   93   94   95   96   97   98   99   100