Có một vấn đề bảo mật nghiêm trọng với giải pháp được đăng bởi Brandon Bodnár (vào thời điểm viết bài này được đánh dấu là giải pháp hợp lệ).
Issue được mô tả ở đây: http://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Min-and-Max.html Và (có giá trị & an toàn) giải pháp cho nó: http://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Typeof.html
Kiểm tra nó ra cho mình:
#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;
}
điều khiển đăng nhập:
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.
Vì vậy không bao giờ sử dụng triển khai ngây thơ như đã thấy trong t ông mã ở trên (và theo đề xuất của Brandon Bodnár, xin lỗi bạn thân;)) nếu bạn muốn tránh những trường hợp xấu nhất như thế này.
Hey Fred, Nếu bạn muốn sử dụng Object-C để làm điều đó, vì vậy hãy sử dụng cú pháp ngôn ngữ, và nếu bạn không hài lòng với điều này, hãy sử dụng C/C++ tinh khiết sẽ thực hiện những gì bạn muốn. bạn muốn. Chúc mừng, – vfn
tại sao có các macro MIN và MAX và một số nền tảng? –
THẬN TRỌNG: Câu trả lời hiện được chấp nhận được coi là không an toàn. (xem bình luận/câu trả lời của tôi) – Regexident