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

完全に正しいかどうかはわかりませんが、私のロジックは次のように述べています。int(符号付き)が0未満の場合、この値は符号なしの値よりも小さくなります。それ以外の場合は、unsignedintにキャストできます

では、これについてはどうでしょうか。

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

これは最良のアイデアですが、「一般的」にすることはできません。UINT_MAX_INTつまり、パラメータの順序を逆にしたい場合は、を作成する必要があります。

Visual Studioを使用していて、警告を聞きたくない場合(問題が発生しないことが確実であるため):http: //msdn.microsoft.com/en-us/library/2c8f766e%28v= vs.80%29.aspx

幸運を

于 2010-12-20T04:30:04.633 に答える
0

私の簡単な提案は、signedおよびunsignedint型について知っていることを使用することです。

多分あなたは試すかもしれません:

#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 に答える