関数である引数を持つマクロの使用に関する警告の言葉。
#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'は2回呼び出されます。1回目は比較<0の場合、2回目は結果-AまたはAを返す場合です。
NSObjCRuntime.hのABSマクロを定義する方法は、追加の変数を導入することでこれを回避しますが、一部の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()を使用する必要があります。