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

C++常规算术转换:cpp.sh与godbolt结果不同,孰是孰非?

问题分析与结论

代码与现象

测试代码如下:

// Example program
#include <iostream>

using namespace std;

int main()
{   
    unsigned long a = 0;
    int b = 1;
    long long c = -1;
    
    cout << (c < a*b) << endl;
}
  • godbolt编译运行返回0
  • cpp.sh编译运行返回1

标准规则依据

C++常规算术转换的核心规则:

  • 若无符号类型U的整数转换秩大于等于有符号类型S的秩,则转换类型为U
  • 否则,若S能表示U的所有值,则转换类型为S
  • 否则,转换为对应于S的无符号整数类型

问题分析

拆解表达式c < a*b的执行逻辑:

  1. 计算a*b:
    a是unsigned long,b是int。由于unsigned long的秩高于int,b会被转换为unsigned long,计算结果为0UL,类型为unsigned long。
  2. 比较c < 0UL:
    在主流64位平台中,unsigned long和long long的秩相同(均为64位整数类型)。按照规则,此时应将long long类型的c(值为-1)转换为unsigned long类型,转换后的值为64位无符号整数的最大值(18446744073709551615)。
    比较该最大值与0UL,结果为false,对应输出0——这符合标准,也是godbolt的正确结果。

不符合标准的编译器

cpp.sh使用的编译器不符合C++标准。原因是它错误地将unsigned long类型的0UL转换为long long类型的0,进而比较-1 < 0得到true并输出1,违反了“无符号类型与有符号类型秩相同时,将有符号类型转换为无符号类型”的规则。

内容的提问来源于stack exchange,提问作者toxic

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 08:53:16