You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SDCC编译时条件判断(x2 + y2 >=800)失效,是否为Bug?

SDCC编译时条件判断失效问题排查

问题现象

这段曼德博集合绘制代码用GCC编译运行完全正常,但用SDCC 4.0.0/4.2.0针对Z80平台编译后,核心条件判断(x2 + y2 >= 800)似乎永远不成立,程序仅输出空格。将变量x和y的类型从int改为long后,程序恢复正常运行,且实际运行中x、y的值从未超过16K范围。

测试代码

#include <stdio.h>

void main()
{
   const char* a[8] = {"\x1b[0m", "\x1b[0;41m", "\x1b[0;42m", "\x1b[0;43m", 
      "\x1b[0;44m", "\x1b[0;45m", "\x1b[0;46m", "\x1b[0;47m"};
   
   int x, y;
   int x2, y2, x0, y0, i, n;
   char c;

   int xa = -500;
   int xb = 300;
   int ya = 240;
   int yb = -250;
   int xd = 7;
   int yd= 15;
   int m = 20;
   
   y0 = ya;
   while (y0 > yb)
   {
      x0 = xa;
      while (x0 < xb)
      {
         y = 0;
         x = 0;
         c = ' ';
         n = 0;
         i = 0;
         while (i < m)
         {
            x2 = (x * x) / 200;
            y2 = (y * y) / 200;
            if ((x2 + y2) >= 800)
            {
               if (i > 9) c = '0'; else c = '0' + i;
               if (i > 7) n = 7; else n = i;
               i = m;
            }
            y = (x * y / 100 + y0);
            x = (x2 - y2 + x0);
            /* if ((x > 16383) || (y > 16383)) printf(" %d %d ", x ,y); */
            i++;
         }
         printf("%s%c", a[n], c);
         x0 = x0 + xd;
      }
      printf("%s\n", a[0]);
      y0 = y0 - yd;
   }
}

SDCC编译命令

$ sdcc -mz80 --no-std-crt0 --data-loc 0 sdc-crt0-args.rel sdc-cpm.rel sdc-mandlebrot.c 
$ sdobjcopy -Iihex -Obinary --gap-fill 0 sdc-mandlebrot.ihx sdc-mandlebrot.com

问题原因

这是16位整数溢出导致的未定义行为,并非SDCC的Bug:

  • Z80平台下SDCC的int是16位有符号整数,取值范围为-32768 ~ 32767
  • 代码中计算x*x时,即使x未超过16K,xx的结果会远大于32767(比如x=16383时,xx≈2.68亿),直接触发16位int的溢出
  • GCC在编译时可能默认使用了更大的临时寄存器或优化策略处理溢出,使得计算结果符合预期;但SDCC严格遵循16位int的运算规则,溢出后得到错误的负数或乱码值,导致x2 + y2永远达不到800的阈值
  • 将x、y改为long后,变量变为32位,足够容纳x*x的计算结果,不会发生溢出,因此逻辑正常执行

结论

代码本身存在跨平台兼容性问题:依赖了GCC对溢出的非标准处理,而SDCC严格遵循16位整数的运算规范,暴露了未定义行为。修改为long类型是正确的修复方式,确保计算过程中不会溢出。

内容的提问来源于stack exchange,提问作者Mike T.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 20:13:27