后置自增(i++)返回旧值,导致判断使用过期数值:如限流中 if ((used = i++) >= max) 会使第 max 次请求仍被放行;重试控制中亦会多执行一轮;前置自增(++i)和独立语句更安全。

因为自增运算符的执行顺序和返回值特性,会让计数器更新与业务判断脱节——看似只差一个“+1”,实则一步错、步步偏。
后置自增(i++)返回旧值,导致判断用的是“过期数字”
比如限流逻辑写成 if ((used = i++) >= max):变量 i 确实加了 1,但赋值给 used 的是自增前的值。结果就是第 max 次请求仍被放行,多放一次;若用于重试控制,还会多执行一轮循环体,触发超额重试。
自增混在表达式里,更新时机不可控
- process(++counter) && counter :前置递增虽保证更新,但短路逻辑可能让
counter 根本不执行,后续判断就失去依据 - log("attempt #" + i++):日志打印的是旧序号,而真实执行已推进到下一步,排查时完全对不上现场
- arr[i++] = value; if (i == len) break;:数组越界访问发生在判断之前,错误已被触发才检查边界
裸变量共享 + 高频循环 = 并发下计数彻底失效
多个线程共用同一个 int counter,在 while(true) 中反复执行 i++,会出现“读-改-写”竞态:两个线程同时读到 100,各自加 1 后都写回 101,实际只增了 1 次。库存扣减、短信发送计次等强一致性场景,直接导致超发或漏扣。
误把数据库自增 ID 当循环索引,跳号引发漏处理或重复
MySQL 的 INSERT ... ON DUPLICATE KEY UPDATE 会预占 auto_increment 值。代码若写 for (int i = 1; i ,而表中实际只有 3 条记录、MAX(id) 却是 8,就会空跑 5 轮——更糟的是,若分页用 WHERE id > ? LIMIT 100,ID 跳变会导致一批记录永远被跳过。











