在项目中,用匿名结构体的地址作为常量来标识不同业务类型(例如 A 、B 、C 、D……),
这样做的目的是彻底避免魔术数字( magic number ),并且希望在逻辑判断中直接通过指针比较。
代码 h 文件
typedef struct __BizType *BizTypeRef;
// 对外暴露的常量声明
extern const BizTypeRef kBizTypeA;
extern const BizTypeRef kBizTypeB;
extern const BizTypeRef kBizTypeC;
extern const BizTypeRef kBizTypeD;
实现文件
// 定义结构体
struct __BizType {
    int value;
};
// 定义常量指针
const BizTypeRef kBizTypeA = &(const struct __BizType){ .value = 1 };
const BizTypeRef kBizTypeB = &(const struct __BizType){ .value = 2 };
const BizTypeRef kBizTypeC = &(const struct __BizType){ .value = 3 };
const BizTypeRef kBizTypeD = &(const struct __BizType){ .value = 4 };
使用
// 使用示例
void handleBiz(BizTypeRef type) {
    if (type == kBizTypeA) {
        // 处理业务 A
    } else if (type == kBizTypeB) {
        // 处理业务 B
    }
}
|  |      1r6cb      19 天前 为什么不用枚举? | 
|      2liuidetmks OP @r6cb 枚举还是数字啊,还是能使用 1 当做参数传入。 我想完全只使用定义的这几个变量,政出一门 | 
|      3aprikyblue      19 天前  2 你看看 enum class | 
|      4cwxiaos      19 天前 via iPhone 或许可以叫做更安全的枚举,限制下游代码乱搞 | 
|  |      5minamo      19 天前 via Android 如果你真这么讨厌魔数,倒也不是不行,但我觉得不值得 | 
|      6iOCZS      19 天前 本该在语法层解决的问题,在用户侧试图解决,会引入复杂性 | 
|  |      7ysc3839      19 天前 via Android  1 这么写的话进行比较时可能并不是直接比较常量,而是要从全局变量里读取值,降低性能。 而且实现文件里这么取临时对象的地址,不怕编译器把这四个对象都优化成使用同一空间?不怕去到悬垂指针出现什么 UB ? 需要枚举类型的地方,能直接传递整数,是 C 允许隐式转换的问题,建议想办法调整编译参数,禁止这种行为,或者迁移到更严格的 C++。 | 
|  |      8xuanbg      19 天前 魔数有什么问题吗?其实魔数一点问题都没有,你先定义一个常量,无非就是脱裤子放屁——多此一举 | 
|      9metalvest      19 天前 为什么不直接用 std::type_index | 
|      10liuidetmks OP @metalvest c @ysc3839 全局作用域不会 ub 吧 比较的话是比较两个指针地址,性能不存在问题的 @xuanbg 有时候业务变化了,魔数可能哪里弄漏了,这里把结构体匿名,提供一个统一构造方法,方便处理一点。 @aprikyblue c | 
|      11kneep      19 天前  1 @liuidetmks @ysc3839 可能是在说全局指针地址的读取可能会多产生一条指令,而常量通常不需要。应该不是在说你比较了指针指向的内容。 | 
|  |      12ysc3839      19 天前 via Android @liuidetmks 地址数值是存在全局变量里的,要先读全局变量,再比较数值 | 
|  |      13geelaw      19 天前  1 @aprikyblue #3 楼主写的是 C 不是 C++,没有 enum class 。(当然,换成 C++ 似乎是比较好的选择。)这一点可以从这段代码可以编译知道(见下面第二点)。 ———— 几个可以挑剔的点: 一双下划线是保留标识符。 二是初始化的时候 constness 不合适,注意 const BizTypeRef 是 struct __BizType * const 而不是 struct __BizType const *,于是这里会丢失 const ,如果实现方(很容易无意间)尝试修改只读复合字面量的 .value 的话会有 UB 。 三是,如果实现方不需要数据,那么实际上没有必要使用 value ,用 non-const 复合字面量本身就可以确保几个表达式的对象不占据相同的位置(但是 const 复合字面量可能会是同一个对象)。 ———— @ysc3839 #7 楼主的版本有不同的值,所以无法是同一个位置。在文件作用域的复合字面量是静态存储期。 | 
|      14cybort      19 天前 via Android 代码静态扫描能解决的问题,为什么要通过编码解决? | 
|  |      15chenxytw      18 天前 Your solution is not better than use `0xdeadbeef01`, `0xdeadbeef02` or other long and unique value to define the enum. The long and unique value is friendly to search and replace. | 
|  |      16coyove      18 天前 楼上已经说了,用魔数 greppability 更好,在超大型项目中更有用 |