比较int和unsigned引用时警告,但比较g++/msvc的const(无ref)时没有警告

Warning when comparing references to int and unsigned but no warning if comparing consts (no ref) with g++/msvc

本文关键字:比较 警告 const ref g++ unsigned int 引用 msvc      更新时间:2023-10-16

我正在编写doctest库,它应该是无警告的。

我最近注意到,在没有警告的情况下进入if语句的代码在我的CHECK()宏中编写时会引起麻烦。

例如:if(0u == 0)不引起警告,而CHECK(0u == 0);引起警告。

我调查了一下,部分原因是CHECK()宏背后有模板和表达式分解以及通过const引用捕获。

我的问题是:

  1. 给定这3个片段-为什么会发生这种情况?

给出警告:

int a = 0;
unsigned b = 0;
if(a == b)

不给出警告:

const int a = 0;
const unsigned b = 0;
if(a == b)

给出警告:

const int& a = 0;
const unsigned& b = 0;
if(a == b)
  • 我该如何解决这个问题?显然,我可以在库头的模板周围使用#pragma diagnostic并沉默这些警告,但这将是不正确的。
  • 原因是如果下面的代码给出一个警告:

    int a = 0;
    unsigned b = 0;
    if(a == b)
    

    那么下一段代码也应该给出一个警告:

    int a = 0;
    unsigned b = 0;
    CHECK(a == b);
    
  • 是否有什么我错过了关于const noref的情况?因为昨天我发布了这个问题,看起来非常相似…是否还有其他的情况会因为模板中的const引用捕获而让我头疼呢?
  • 我不认为编译器或优化级别的问题-我已经尝试了几个版本的g++/MSVC (/W4的MSVC和-Wall -Wextra -pedantic + 50以上的g++),可能clang做同样的…

    编辑:

    下面的代码在g++中产生了一个警告,但在msvc中没有…(-Wsign-conversion)

    const int a = -1;
    const unsigned b = 0;
    if(a == b)
    

    通常unsigned int可以表示比int更大的值。虽然可以将unsigned int转换为int,但在某些情况下会失败。例如,在2补码表示法中,-1被转换为unsigned int中最大的数字(假设两者都使用相同大小的容器/寄存器)。

    注意,当你使用const来引用时,这是正确的,因为一些引用可以在运行时初始化。例如,当你说一个函数的参数中有const引用时。只有在调用时才知道它的值。

    另一方面,const intconst unsigned int的值在编译时是已知的。编译器知道如何从另一个转换,并且没有副作用,所以不需要警告。

    如何应对这种情况?只要使用它们之间相等的类型。如果您确实想使用不同的类型并了解其副作用,您可以告诉编译器您知道自己在做什么,并执行强制类型转换(static_cast)。

    在比较两个变量时得到警告是完全正常的,一个有符号,一个无符号。对于常量则不同:

    这段代码没有给出警告,因为ab是在编译时求值的,并且都被0替换。

    将这段代码编译:

    const int a = 0;
    const unsigned b = 0;
    if(a == b)
    {
       c =15;
    }
    else
    {
       c=67;
    }
     cout << c << endl;
    

    a==b部分周围拆卸:

    if(a == b)
    {
            c=15;
      1d:   c7 45 f4 0f 00 00 00    movl   $0xf,-0xc(%rbp)
    else
    {
            c = 67;
    }
    cout << c << endl;
    

    跳过测试,跳过else…为什么编译器会发出警告?

    此行为有时被开发人员用来禁用部分代码:在航空业务中,不可访问的代码是被禁止的。该机制确保不生成任何代码。审计可以证明在机器码级别没有死代码。