如何让编译器对自定义整数类型的非法混合操作触发告警?
实现专用类型混合操作的编译检查
因为typedef只是给uint64_t起别名,编译器仍会将tIDX、tSIZE、tVALUE视为同一类型,所以无法触发类型不匹配的告警。要实现你需要的类型检查,必须让编译器认为这些是不同的类型,而非同一类型的别名,具体可以分C和C++两种场景实现:
C++ 方案(推荐,运算符重载更自然)
用结构体封装原始整数,只重载允许的运算符,不支持的混合操作会直接触发编译错误(比告警更严格可靠):
#include <cstdint> // 定义不同的结构体类型,编译器会视为完全不同的类型 struct tIDX { uint64_t val; }; struct tSIZE { uint64_t val; }; struct tVALUE { uint64_t val; }; // 允许的操作:两个索引相加 tIDX operator+(tIDX a, tIDX b) { return {a.val + b.val}; } // 允许的操作:索引加数值 tIDX operator+(tIDX a, tVALUE b) { return {a.val + b.val}; } tIDX operator+(tVALUE a, tIDX b) { return {a.val + b.val}; } // 可选:支持复合赋值操作 tIDX& operator+=(tIDX& a, tVALUE b) { a.val += b.val; return a; }
使用时,合法操作能正常编译,比如:
tIDX idx1 = {10}, idx2 = {20}; tVALUE val = {5}; auto sum_idx = idx1 + idx2; // 合法 auto idx_plus_val = idx1 + val; // 合法
而不允许的操作(比如tIDX + tSIZE)会直接触发编译错误,提示没有匹配的运算符,达到你需要的检查效果。
C 方案(无运算符重载,用函数封装操作)
C语言不支持运算符重载,所以需要用函数来封装允许的操作,强制开发者通过函数进行合法运算,直接混合结构体操作会触发编译错误:
#include <stdint.h> typedef struct { uint64_t val; } tIDX; typedef struct { uint64_t val; } tSIZE; typedef struct { uint64_t val; } tVALUE; // 允许的操作:两个索引相加 tIDX tIDX_add_tIDX(tIDX a, tIDX b) { tIDX res = {a.val + b.val}; return res; } // 允许的操作:索引加数值 tIDX tIDX_add_tVALUE(tIDX a, tVALUE b) { tIDX res = {a.val + b.val}; return res; }
使用时,必须通过函数进行合法操作:
tIDX idx1 = {10}, idx2 = {20}; tVALUE val = {5}; tIDX sum_idx = tIDX_add_tIDX(idx1, idx2); // 合法 tIDX idx_plus_val = tIDX_add_tVALUE(idx1, val); // 合法
如果直接写idx1.val + size.val(直接访问成员),虽然能编译,但你可以通过代码规范禁止直接访问结构体成员,只允许通过封装的函数操作,配合静态代码检查工具(比如clang-tidy)来约束。
补充说明
如果一定要让编译器触发告警而非错误,可以借助GCC/Clang的__attribute__((deprecated))或自定义属性,但这种方式不如强类型检查可靠,开发者可能忽略告警。而上面的强类型方案直接阻断不合法操作,更符合你的需求。
内容的提问来源于stack exchange,提问作者virolino
相关产品推荐
相关产品推荐

