Getting rid of the gcc shift with a negative warning

I have a code that looks like this:

template<unsigned int A, unsigned int B>
int foo() {
  int v = 1;
  const int x = A - B;
  if (x > 0) {
    v = v << x;
  }
  bar(v);
}

gcc will complain that x is negative for specific instances of A, B; however, I do a check to make sure it is non-negative. What is the best way? I know that I can use xhow unsigned int, but this will result in warnings about xbeing larger than the width v(since he put the negative number as positive). I know that there is work involved in creating a new templatized function shift, but I would like to avoid this if possible.

+3
source share
3 answers

A B , , if - , :

#include <iostream>
using namespace std;

template< unsigned int A, unsigned int B >
struct my
{
    template< bool P >
    static void shift_if( int & );

    template<>
    static void shift_if< false >( int & ) {}

    template<>
    static void shift_if< true >( int & v ) { v <<= A - B; }

    static void op( int & v ) { shift_if< (A > B) >( v ); }
};

template< unsigned int A, unsigned int B >
int foo()
{
    int v = 1;
    my< A, B >::op( v );
    return v;
}

int main() {
    cout << foo< 1, 3 >() << endl;
    cout << foo< 3, 1 >() << endl;
    cout << foo< 300, 1 >() << endl;
    cout << foo< 25, 31 >() << endl;
    return 0;
}
+3

x char ? 255 ?

const unsigned char x = static_cast<unsigned char>(A - B);

, , , , :

const unsigned int x = static_cast<unsigned int>(A - B) & 0x1f; // limit A-B to have a range of (0 - 31)

EDIT:

:

template<unsigned int A, unsigned int B>
int foo() {
  int v = 1;
  const int x = A - B;
  if (x > 0) {
    v = v << (static_cast<unsigned int>(x) & 0x1f);
  }
  bar(v);
}

: 0x1f - : (CHAR_BIT * sizeof (T) - 1)

EDIT: , : g++ -W -Wall -ansi -pedantic test.cc -o test

#include <iostream>

template<unsigned int A, unsigned int B>
int foo() {
  int v = 1;
  const int x = A - B;
  if (x > 0) {
    v = v << (static_cast<unsigned int>(x) & 0x1f);
  }
  return v;
}

int main() {
    std::cout << foo<1, 3>() << std::endl;
    std::cout << foo<3, 1>() << std::endl;
    std::cout << foo<300, 1>() << std::endl;
    std::cout << foo<25, 31>() << std::endl;
}
+2

?

const short unsigned int x = A - B;

, , A - B ...

0

Source: https://habr.com/ru/post/1699189/


All Articles