如何用C++预处理器在编译时校验数组元素和与宏定义值相等
编译时检查数组元素总和与宏定义值是否匹配
我的C++应用里有这么一段配置代码:
#define LED_SIZE 113 #define SEGMENT_SIZE 3 const int LED_SEGMENTS[SEGMENT_SIZE] = {30, 70, 13};
我得验证这个数组里的元素加起来是不是等于LED_SIZE(也就是30+70+13=113),而且要在编译时通过预处理器指令完成检查,要是总和不对,直接让编译失败。
方法一:纯预处理器实现
预处理器没法直接读取数组元素求和,所以得把数组元素先定义成宏参数,让预处理器能拿到这些值计算:
#define LED_SIZE 113 #define SEGMENT_SIZE 3 // 把数组元素单独定义成宏,方便预处理器处理 #define LED_SEGMENT_VALUES 30, 70, 13 // 预处理器求和的宏,这里要对应SEGMENT_SIZE的元素个数 #define SUM(...) SUM_INTERNAL(__VA_ARGS__, 0) #define SUM_INTERNAL(a, b, c, ...) (a + b + c) // 编译时检查,不匹配就报错 #if SUM(LED_SEGMENT_VALUES) != LED_SIZE #error "LED_SEGMENTS总和和LED_SIZE不匹配!" #endif // 用宏初始化数组 const int LED_SEGMENTS[SEGMENT_SIZE] = {LED_SEGMENT_VALUES};
注意:如果SEGMENT_SIZE变了,比如改成4个元素,那SUM_INTERNAL的参数也要跟着加一个,比如改成SUM_INTERNAL(a, b, c, d, ...) (a+b+c+d),这种方法需要手动适配元素个数。
方法二:C++11及以上用constexpr+static_assert(更灵活)
如果你的项目支持C++11或更高版本,这个方法比纯预处理器更方便,不用手动适配元素个数:
#define LED_SIZE 113 #define SEGMENT_SIZE 3 constexpr int LED_SEGMENTS[SEGMENT_SIZE] = {30, 70, 13}; // 编译时计算数组总和的constexpr函数 constexpr int calculate_array_sum(const int arr[], int size) { int sum = 0; for (int i = 0; i < size; ++i) { sum += arr[i]; } return sum; } // 静态断言,编译时检查总和是否匹配 static_assert(calculate_array_sum(LED_SEGMENTS, SEGMENT_SIZE) == LED_SIZE, "LED_SEGMENTS总和与LED_SIZE不匹配!");
这种方式下,编译器会在编译阶段就计算数组总和并检查,不满足条件直接抛出编译错误,而且数组元素个数变化时不用修改求和逻辑,更省心。
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

