在比较int和unsigned的引用时发出警告,但如果将consts(no ref)与g ++ / msvc进行比较,则不会发出警告 [英] Warning when comparing references to int and unsigned but no warning if comparing consts (no ref) with g++/msvc

查看:415
本文介绍了在比较int和unsigned的引用时发出警告,但如果将consts(no ref)与g ++ / msvc进行比较,则不会发出警告的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我正在写 doctest 库,它应该是免费的警告。



我最近注意到,如果语句没有警告,进入的代码在写入< CHECK() macro。



例如: if(0u == 0)不会导致警告,但 CHECK(0u == 0); 不会。



部分原因是在 CHECK()宏后面有模板和表达式分解和通过const引用捕获。



我的问题是3:


  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 ,并将这些警告消音,但这样做不正确。

    原因是,如果下面的代码给出了一个警告:

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

    然后下一段代码也应该给出警告:

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




    1. 有没有关于const noref大小写?因为昨天我发布了这个这个看起来惊人相似的问题......还有其他一些情况会因为这个俘获在我的模板中通过const引用?

    我不认为编译器或优化级别很重要 - 我尝试了几个版本对于msvc和 -Wall -Wextra -pedantic + / W4 //github.com/onqtam/doctest/blob/master/scripts/common.cmake#L74rel =nofollow noreferrer> 50更多 for 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 int 或<$ c $ c> const unsigned int 在编译时已知它的值。编译器知道如何从其他方面进行转换,并且没有副作用,因此不需要警告。



    如何对付这种情况?只需使用它们之间相同的类型即可。如果你真的想要使用不同的类型并且知道副作用,你可以告诉编译器你知道你在做什么并且执行一次cast(static_cast)。


    So I'm writing the doctest library and it's supposed to be warning free.

    I recently noticed that code that went into an if statement without warnings was causing trouble when written inside of my CHECK() macro.

    For example: if(0u == 0) doesn't cause a warning but CHECK(0u == 0); does.

    I investigated a bit and part of the reason is that behind the CHECK() macro there are templates and expression decomposition and capturing by const reference.

    My questions are 3:

    1. Given these 3 snippets - why does this happen?

    gives a warning:

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

    doesn't give a warning:

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

    gives a warning:

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

    1. How can I combat this? Obviously I can use #pragma diagnostic around the templates in the library header and silence these warnings but this will not be correct.

    The reason is that if the following code gives a warning:

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

    then the next piece of code should also give a warning:

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

    1. Is there something I'm missing about the const noref case? Because yesterday I posted this question which seems strikingly similar... Are there other cases that will bite me by the ass because of this capturing by const reference in my templates?

    I don't think the compiler or the optimization levels matter - I've tried a few versions of g++/MSVC (/W4 for msvc and -Wall -Wextra -pedantic + 50 more for g++) and probably clang does the same...

    EDIT:

    The following code produced a warning with g++ but did NOT with msvc... (-Wsign-conversion)

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

    解决方案

    Usually a unsigned int can represent larger values than an int. While you can convert an unsigned int to an int, there are cases where it will fail. For example, in a 2 complement notation, a -1 is converted to the largest number in a unsigned int (assuming that both are using a container / register of same size).

    Note that this is true when you use const to reference, because some references can be initialized at runtime. For example, when you say that a function has in its arguments const references. You will only knows its values at calling times.

    By the other hand, a const int or const unsigned int has its values known at compile time. Compiler knows how to convert from which other and there is no sides effects, so no warning is required.

    How to combat this situation? Just use type that are equal between them. If you really want to use different types and know the side effects, you can tell compiler that you know what you are doing and do a cast (static_cast).

    这篇关于在比较int和unsigned的引用时发出警告,但如果将consts(no ref)与g ++ / msvc进行比较,则不会发出警告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆