3

假设什么是安全修复“有符号整数和无符号整数之间的比较”警告的首选方法?就我而言,我必须将一些 uint_32 变量与#define 常量进行比较。

真正简化:

#define MAX(A,B) ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __b : __a; })
#define c (10)
unsigned int d = 11;
if(MAX(c,d)>10){
  //...
}

但我真的有很多这样的案例——你会建议什么来解决这个问题?

4

4 回答 4

4

在这种情况下,您也可以将常量更改为无符号:

#define c 10U

或者,使用强制转换以便typeof在您的宏中创建一个unsigned变量:

if (MAX((unsigned)c, d) > 10) {
于 2010-12-20T04:52:28.417 回答
1

I don't know if is totally correct but my logic says this: If an int (signed) is < 0, this value is lesser than the unsigned one. Otherwise, you can just cast it to an unsigned int

So what about this:

#define INT_MAX_UINT(value1,value2) (value1<0?value2:(((uint)value1)>value2?value1:value2))

This is the best idea, however you cannot make it "generic", I mean you have to build a UINT_MAX_INT if you want reverse the params order

If you are using Visual Studio and you simply don't want to hear the warning (because you are sure it will not give any problem): http://msdn.microsoft.com/en-us/library/2c8f766e%28v=vs.80%29.aspx

Good luck

于 2010-12-20T04:30:04.633 回答
0

我的简单建议是使用您对有符号和无符号 int 类型的了解。

也许你可以尝试:

#include <limits.h>

unsigned int max(int six, unsigned int uix) {
   if (uix > INT_MAX || six < 0) { return uix; }
   return ((unsigned int) six >= uix) ? (unsigned int) six : uix;
}

注意“类型传染”(我想不出更好的词来形容它,因为效果是隐含的)

你甚至可以内联这个函数。

于 2010-12-20T06:34:18.197 回答
-1

我使用“保值”的 C++ 促销。问题是如何找到需要提升的操作数。有符号无符号之间的比较相当于检查有符号数是否为正之后的无符号比较。如果两个数字的大小相同,我将其转换为无符号数,否则我将其转换为最大的数字。下一个不太相等的模板实现对我来说很好。

/*
 * Signed unsigned safe less equal function implementation
 * 
 * a <=b
 * int uint --> (a <= 0) || ( b >= (B)a  && a <= (A)b )
 * uint int --> (b >= 0) && ( a <= (A)b  && b >= (B)a )
 *
 * all comparations are done using positive numbers
 * If integral promotion is used then one condition can be remove
 *
 *  a <= b
 * int  uint --> (a <=0) ||  [ (uint)a <= b | a <= (int)b ]
 * uint int  --> (b >=0) ||  [ (uint)a <= b | a <= (int)b ]
 *
 * The question is. cast to B or to A?
 *
 *  size A = size B
 *  uint <= int  A
 *  int  <= uint B
 *
 *  size A > size B
 *  uint <= int  A
 *  int  <= uint A
 *
 *  size A < size B
 *  uint <= int B
 *  int <= uint B
 */
namespace Range
{
    /*
     * if sizeof A > sizeof B then casting to A
     * if sizeof A < sizeof B then casting to B
     * if sizeof A == sizeof A then
     *  if A is signed cast to B else cast to A
     *
     * true means static cast to A
     */
    template<size_t a,size_t b,bool intA>
    struct _le_cast_to_a_
    {
        constexpr static const bool value = (a > b) ? true : (a < b) ? false : intA ? false : true;
    };

    // Casting to A default implementation
    template<bool cast_to_a = true>
    struct _less_equal
    {
        template <class A,class B>
        static inline bool le(A a,B b)
        {
            return (a <= static_cast<A>(b));
        }
    };
    // Casting to b specialization
    template<>
    struct _less_equal<false>
    {
        template <class A,class B>
        static inline bool le(A a,B b)
        {
            return (static_cast<B>(a) <= b);
        }
    };
    /*
     * Parameter
     * is A int, is B int
     */
    template<bool intA,bool intB>
    struct _impl1_
    {
        template<class A,class B>
        static inline bool less_equal(A a,B b)
        {
            return a <= b;
        }
    };
    // Specialization for uint int
    template<>
    struct _impl1_<false,true>
    {
        template<class A,class B>
        static inline bool less_equal(A a,B b)
        {
            return (b >=0) && _less_equal< _le_cast_to_a_<sizeof(A),sizeof(B),std::is_signed<A>::value >::value >::le(a,b);
        }
    };
    // Specialization for int uint
    template<>
    struct _impl1_<true,false>
    {
        template<class A,class B>
        static inline bool less_equal(A a,B b)
        {
            return (a <=0) || _less_equal< _le_cast_to_a_<sizeof(A),sizeof(B),std::is_signed<A>::value >::value >::le(a,b);
        }
    };

    template<class A, class B>
    static bool less_equal(A a, B b)
    {
        return _impl1_<std::is_signed<A>::value,std::is_signed<B>::value>::less_equal(a, b);
    }

    template<class V, class T>
    static bool check(V v, T start, T end)
    {
        return less_equal(start, v) && less_equal(v, end);
    }

    void test()
    {
        volatile char c = 7;
        volatile unsigned char uc = 0xAA;
        volatile int i = -1;
        volatile unsigned int ui = 0xF000;
        volatile bool b;

        b = less_equal(c, uc);
        b = less_equal(uc, c);

        b = less_equal(c, i);
        b = less_equal(i, c);

        b = less_equal(ui, uc);
        b = less_equal(uc, ui);

        b = less_equal(i, uc);
        b = less_equal(uc, i);
        b = less_equal(ui, c);

        b = less_equal(c, ui);
        b= (c <=0) || (static_cast<unsigned int>(c) <= ui);
        b= (c <=0) || (c <= static_cast<char>(ui));
    }
}
于 2015-01-22T22:30:22.583 回答