How would you define a simple “min” method in obj-c

前端 未结 7 2244
感动是毒
感动是毒 2020-12-16 11:42

I want to define a min and max methods in a Utils class.

@interface Utils

int min(int a, int b);
int max(int a, int b);

@end

But I don\'t

7条回答
  •  暗喜
    暗喜 (楼主)
    2020-12-16 12:12

    There's a serious issue with the solution posted by Brandon Bodnár (which by the time of this writing is marked as a valid solution).

    Issue described here: http://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Min-and-Max.html And the (valid & secure) solution to it: http://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Typeof.html

    Check it out yourself:

    #include 
    
    #define NAIVE_MAX(a,b) (a > b ? a : b)
    
    #define NAIVE_MIN(a,b) (a < b ? a : b)
    
    #if !defined MAX
    #define MAX(a,b) \
    ({ __typeof__ (a) __a = (a); \
    __typeof__ (b) __b = (b); \
    __a > __b ? __a : __b; })
    #endif
    
    #if !defined MIN
    #define MIN(a,b) \
    ({ __typeof__ (a) __a = (a); \
    __typeof__ (b) __b = (b); \
    __a < __b ? __a : __b; })
    #endif
    
    int main (int argc, const char * argv[]) {
        int a = 3;
        int b = 5;
    
    #pragma mark NON-FATAL CASES:
        printf("NAIVE_MAX(%d, %d) => %d\n", a, b, NAIVE_MAX(a, b));
        printf("NAIVE_MIN(%d, %d) => %d\n", a, b, NAIVE_MIN(a, b));
    
        printf("MAX(%d, %d) => %d\n", a, b, MAX(a, b));
        printf("MIN(%d, %d) => %d\n", a, b, MIN(a, b));
    
        printf("\nEverything fine so far...\n\n");
    
    #pragma mark FATAL CASES:
        //cache:
        int _a = a;
        int _b = b;
        printf("NAIVE_MAX(%d++, %d++) => %d\n", _a, _b, NAIVE_MAX(a++, b++));
    
        //reset:
        a = _a;
        b = _b;
        printf("NAIVE_MIN(%d++, %d++) => %d\n", _a, _b, NAIVE_MIN(a++, b++));
    
        //reset:
        a = _a;
        b = _b;
        printf("NAIVE_MAX(++%d, ++%d) => %d\n", _a, _b, NAIVE_MAX(++a, ++b));
    
        //reset:
        a = _a;
        b = _b;
        printf("NAIVE_MIN(++%d, ++%d) => %d\n", _a, _b, NAIVE_MIN(++a, ++b));
    
        printf("\nOuch, this doesn't look right at all!\n\n");
    
    #pragma mark NON-FATAL CASES:
        //reset:
        a = _a;
        b = _b;
        printf("MAX(%d++, %d++) => %d\n", _a, _b, MAX(a++, b++));
    
        //reset:
        a = _a;
        b = _b;
        printf("MIN(%d++, %d++) => %d\n", _a, _b, MIN(a++, b++));
    
        //reset:
        a = _a;
        b = _b;
        printf("MAX(++%d, ++%d) => %d\n", _a, _b, MAX(++a, ++b));
    
        //reset:
        a = _a;
        b = _b;
        printf("MIN(++%d, ++%d) => %d\n", _a, _b, MIN(++a, ++b));
    
        printf("\nAh, much better now.\n\n");
    
        return 0;
    }
    

    Console log:

    NAIVE_MAX(3, 5) => 5
    NAIVE_MIN(3, 5) => 3
    MAX(3, 5) => 5
    MIN(3, 5) => 3
    
    Everything fine so far...
    
    NAIVE_MAX(3++, 5++) => 6
    NAIVE_MIN(3++, 5++) => 4
    NAIVE_MAX(++3, ++5) => 7
    NAIVE_MIN(++3, ++5) => 5
    
    Ouch, this doesn't look right at all!
    
    MAX(3++, 5++) => 5
    MIN(3++, 5++) => 3
    MAX(++3, ++5) => 6
    MIN(++3, ++5) => 4
    
    Ah, much better now.
    

    So never ever use the naive implementation as seen in the code above (and as suggested by Brandon Bodnár, sorry buddy ;) ) if you want to avoid worst cases like these.

提交回复
热议问题