C++自定义DateTime结构体高效比较实现的遗漏场景排查
问题描述
我定义了如下DateTime结构体:
struct DateTime { std::uint16_t year; std::uint8_t month; std::uint8_t day; std::uint8_t hour; std::uint8_t minute; std::uint8_t second; std::uint16_t milisecond; };
在实现LessThan和GreaterThan方法时,为了避免堆砌大量if/else分支编写了如下逻辑,但不确定是否覆盖了所有比较场景:
bool GreaterThan(const DateTime& datetime) { bool greater{true}; // When found a different value for the most significant value, the evaluation is interrupted if ((year <= datetime.year) && (month <= datetime.month || year < datetime.year) && (day <= datetime.day || month < datetime.month) && (hour <= datetime.hour || day < datetime.day) && (minute <= datetime.minute || hour < datetime.hour) && (second <= datetime.second || minute < datetime.minute) && (milisecond <= datetime.milisecond || second < datetime.second)) { greater = false; } return greater; } bool LessThan(const DateTime& datetime) { bool less{true}; // When found a different value for the most significant value, the evaluation is interrupted if ((year >= datetime.year) && (month >= datetime.month || year > datetime.year) && (day >= datetime.day || month > datetime.month) && (hour >= datetime.hour || day > datetime.day) && (minute >= datetime.minute || hour > datetime.hour) && (second >= datetime.second || minute > datetime.minute) && (milisecond >= datetime.milisecond || second > datetime.second)) { less = false; } return less; }
未覆盖的错误场景与实现缺陷
你的实现存在核心逻辑漏洞,以下场景会返回完全错误的结果:
- 跨周期非相邻高位更小的场景判断完全错误:你的设计思路是"只要高位字段已经小于对比值,低位字段不需要再判断",但实际写条件时,每个低位的跳过判断仅检查了紧邻的上一级高位是否更小,遗漏了更上层高位的判断。比如判断日字段时,你只写了
month < datetime.month作为跳过日比较的条件,没有考虑年更小但月更大的跨年场景:拿2023-12-31和2024-01-01比较,年字段2023<2024,本应直接判定当前时间更小,但走到日字段判断时,month < datetime.month即12 < 1不成立,day <= datetime.day即31 <=1也不成立,整个if条件直接判定为假,GreaterThan错误返回true。同类错误会出现在所有低位判断中:判断小时只检查了日是否更小,没考虑月、年更小的情况;判断分钟只检查了小时是否更小,没考虑日、月、年更小的情况,所有跨两个字段及以上的时间差场景(比如年末对比次年初、月末对比次月初、日尾对比次日零点)都会判断错误。 - 比较逻辑不互斥:以上述跨年场景为例,
GreaterThan会错误返回true,LessThan也会返回true,两个互斥的判断同时成立,完全不符合比较逻辑的基本要求。 - 额外细节问题:结构体字段
milisecond存在拼写错误,正确拼写应为millisecond,虽然不影响逻辑运行,但会降低代码可读性。
优化建议
完全不需要为了减少if分支强行拼接复杂的长逻辑表达式,按字段优先级从高到低短路判断的写法非常简洁,且可读性、正确性都有保障:
// 大于判断 bool GreaterThan(const DateTime& other) const { if (year != other.year) return year > other.year; if (month != other.month) return month > other.month; if (day != other.day) return day > other.day; if (hour != other.hour) return hour > other.hour; if (minute != other.minute) return minute > other.minute; if (second != other.second) return second > other.second; return milisecond > other.milisecond; } // 小于判断 bool LessThan(const DateTime& other) const { if (year != other.year) return year < other.year; if (month != other.month) return month < other.month; if (day != other.day) return day < other.day; if (hour != other.hour) return hour < other.hour; if (minute != other.minute) return minute < other.minute; if (second != other.second) return second < other.second; return milisecond < other.milisecond; }
不要尝试用memcmp直接比较结构体内存,因为结构体存在内存对齐填充字节,填充值不确定会导致比较结果随机出错。
内容的提问来源于stack exchange,提问作者Maf
相关产品推荐
相关产品推荐

