通常,除了提供函数声明外,C 标准头文件还可能提供“掩码宏”以加快处理速度。例如,如果我包含ctype.h
,头文件将声明
int isdigit(int c);
但它也可能用宏掩盖声明。isdigit
我相信这是一个符合 C 标准的可移植宏:
#define isdigit(c) ((c) >= '0' && (c) <= '9')
当然,这个宏也很危险,因为如果在定义宏时这样做,它会引入未定义的行为:
int c = 'A';
printf("%d\n", isdigit(c++));
为了避免在这种假设情况下出现 UB,我必须将函数名称用括号括起来: (isdigit)(c++)
。所以,我的问题是:标准头文件可以定义什么样的掩码宏有任何限制吗?如果参数表达式有副作用,它们是否保证不会导致未定义的行为,或者它们在技术上是否允许具有我们上面看到的奇怪行为?界限在哪里?