C'è un serio problema di sicurezza con la soluzione pubblicata da Brandon Bodnár (che al momento della stesura di questo documento è contrassegnata come una soluzione valida).
problema descritto qui: http://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Min-and-Max.html E la (& valida sicuro) soluzione ad esso: http://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Typeof.html
controllare voi stessi:
registro
#include <stdio.h>
#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:
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.
Così mai e poi mai usare l'ingenua implementazione come visto in t codice sopra (e come suggerito da Brandon Bodnár, amico spiacente;)) se vuoi evitare casi peggiori come questi.
Ehi Fred, Se vuoi usare Object-C per farlo, usa la sintassi del linguaggio, e se non sei soddisfatto, usa puro C/C++, che farà quello che vuoi, nel modo in cui tu vuoi. Cheers, – vfn
perché ci sono allora MIN e MAX macro e alcune piattaforme? –
ATTENZIONE: la risposta attualmente accettata è considerata non sicura. (vedere il mio commento/risposta) – Regexident