#include <stdio.h>
#define ARRAY_SUM(arr, len) \
({ \
int sum = 0; \
const int *p = (arr); \
int l = (len); \
for (int i = 0; i < l; ++i) { \
sum += p[i]; \
} \
sum; \
})
int main() {
int arr[] = {1, 2, 3, 4, 5};
int len = sizeof(arr) / sizeof(arr[0]);
int result = ARRAY_SUM(arr, len);
printf("Sum of array elements: %d\n", result);
return 0;
}
避免副作用措施的原理
- 使用临时变量:在宏中使用了临时变量
sum
、p
和 l
来存储中间结果和输入参数。这样做是为了避免对传入的数组指针 arr
和数组长度 len
直接进行操作。如果不使用临时变量,宏在多次使用 arr
和 len
时可能会导致副作用,比如 len
被多次求值(如果 len
是一个表达式)。例如,如果 len
是一个包含自增操作的表达式,直接使用 len
会导致 len
的值在宏内部多次变化,结果不符合预期。
- 使用
const
修饰指针:将数组指针 p
声明为 const int *
,这样可以防止宏内部意外修改传入的数组内容。如果没有 const
修饰,宏函数内部可能不小心对数组进行了修改,这在一些场景下会导致严重的副作用。
- 使用
({ })
复合语句表达式:在C99标准中,({ })
复合语句表达式允许在其中定义局部变量,并返回最后一个表达式的值。这种方式可以将宏函数的逻辑封装起来,避免与外部代码产生命名冲突等副作用。如果不使用 ({ })
,宏内部定义的变量(如 sum
、p
和 l
)可能会与调用宏的代码中的变量重名,导致意外的结果。