代码之家  ›  专栏  ›  技术社区  ›  Andrew Truckle

警告C26454:算术溢出:“-”运算在编译时生成负的无符号结果(IO.5)

  •  3
  • Andrew Truckle  · 技术社区  · 6 年前

    代码分析:

    ON_NOTIFY(TCN_SELCHANGE, IDC_TAB_HISTORY_TYPE,
      &CAssignHistoryDlg::OnTcnSelchangeTabHistoryType)
    

    警告C26454:

    算术溢出:“-”运算产生负的无符号结果 在编译时(IO.5)。

    定义 TCN_SELCHANGE 是:

    #define TCN_FIRST (0U-550U)
    #define TCN_SELCHANGE           (TCN_FIRST - 1)
    

    我看不出还能做什么!

    2 回复  |  直到 6 年前
        1
  •  1
  •   Casey    6 年前

    您试图从一个较小的无符号值中减去一个较大的无符号值,这将导致结果超过零。在您的情况下,我假设tcn_first定义为0,因此将tcn_selchange设置为1将解决问题。

    你也应该使用 constexpr const 而不是定义。

    根据msdn:

    Arithmetic overflow checks in C++ Core Check

    C26451 RESULT_OF_ARITHMETIC_OPERATION_CAST_TO_LARGER_SIZE :[operator]操作在编译时换行超过0并生成一个大的无符号数字。此警告表示减法运算产生一个在无符号上下文中计算的负结果。这会导致结果超过0并产生一个真正大的无符号数,从而导致意外的溢出。

    1 // Example source:
    2 unsigned int negativeunsigned() {
    3    const unsigned int x = 1u - 2u; // C26454 reported here
    4    return x;
    5 }
    
    1 // Corrected source:
    2 unsigned int negativeunsigned() {
    3     const unsigned int x = 4294967295; // OK
    4     return x;
    5 }
    

    在校正的源中,一个正值被分配给无符号的结果。

        2
  •  2
  •   Barmak Shemirani    6 年前
    //windows头文件:
    #先定义tcn_(0u-550u)
    #定义tcn_selchange(tcn_first-1)
    
    //用户文件:
    …
    无符号int i=tcn_selchange;
    

    以上代码在C++中是有效的,编译时不需要任何警告。没有溢出,这只意味着-550u如果他们将其写为define tcn ou first 0xfffffffdda0xfffffffffu-549u,则会更清楚。

    代码分析似乎使用了一种不同的方法,并看到溢出。

    可能的解决方案:

    禁用代码中的警告:

    pragma warning(push)
    #pragma警告(禁用:26454)
    
    开始_消息_映射(cmydialog,cdialogex)
    通知时(tcn_selchange,idc_tab1,ontcnselchangetabHistoryType)
    结束消息映射()
    
    #pragma警告(pop)
    
    
    

    或者,禁用代码分析规则中的警告
    use the code analysis rule set editor

    上面的代码在C++中是有效的,它应该编译而不需要任何警告。没有溢出,这是注定的-550U如果他们把它写成#define TCN_FIRST 0xFFFFFDDA0xFFFFFFFFU-549U

    代码分析似乎使用了不同的方法并看到溢出。

    可能的解决方案:

    禁用代码中的警告:

    #pragma warning( push )
    #pragma warning( disable : 26454 )
    
    BEGIN_MESSAGE_MAP(CMyDialog, CDialogEx)
        ON_NOTIFY(TCN_SELCHANGE, IDC_TAB1, OnTcnSelchangeTabHistoryType)
    END_MESSAGE_MAP()
    
    #pragma warning( pop )
    

    或者,禁用代码分析规则中的警告
    Use the code analysis rule set editor

    enter image description here