Слово предупреждения об использовании макросов с аргументами, которые являются функциями, например.
#include <stdio.h>
#define BAD_ABS(A) ((A)<0 ? (-(A)):(A))
int afunc(){
printf("afunc was called\n");
return 1;
}
int main(void){
int a;
a = BAD_ABS(afunc());
/* this has the result of:
a = (afunc()<0) ? (-(afunc())) : (afunc());
*/
}
Функция «afunc» будет называться дважды, сначала для сравнения < 0 и второй, когда он возвращает результат -A или A.
способ, макро АБС в NSObjCRuntime.h определен избегает этого, вводя дополнительную переменную, но некоторые макросы DIY могут не быть, например Я видел в нескольких местах
#define BAD_ABS(a) ((a)<0 ? (-(a)) : (a))
Ухудшается, если вызываемая функция является генератором случайных чисел, например.
#include <stdio.h>
#include <stdlib.h>
int main(void){
short seeds[] = {1,2,3};
int i;
for(i=0;i<10000;i++) printf("%ld\n", BAD_ABS(jrand48(seeds)));
}
У этого есть 50-50 шанс вернуть отрицательное число !!!
Если, с другой стороны, вы хотите использовать функцию stdlib abs(), тогда предупреждайте, что она не будет работать с длинными целыми числами. В этом случае вы должны использовать labs().
Ahhhh. Я вижу! СПАСИБО! Так ли я прав, что abs (int) всегда возвращал целое число? – Hexark
@Hexark, да, это – Habib