Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 通过负面警告消除gcc移位_C++_Gcc - Fatal编程技术网

C++ 通过负面警告消除gcc移位

C++ 通过负面警告消除gcc移位,c++,gcc,C++,Gcc,我有一些代码看起来像: 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); } 模板 int foo(){ int v=1; 常数int x=A-B; 如果(x>0){ 这行吗 const short unsigned int x = A - B;

我有一些代码看起来像:

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);
}
模板
int foo(){
int v=1;
常数int x=A-B;
如果(x>0){
这行吗

const short unsigned int x = A - B;

它所截取的位比需要截取的位多得多,但是如果a-B的值足够小,为什么不将x设为无符号字符类型并强制转换它呢?当然,您不需要移动超过255位

const unsigned char x = static_cast<unsigned char>(A - B);
const unsigned char x=static_cast(A-B);
或者可以使用掩蔽来确保偏移在如下边界内:

const unsigned int x = static_cast<unsigned int>(A - B) & 0x1f; // limit A-B to have a range of (0 - 31)
#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;
}
const unsigned int x=static_cast(A-B)&0x1f;//限制A-B的范围为(0-31)
编辑:

作为对评论的回应,这里有一个想法:

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);
}
模板
int foo(){
int v=1;
常数int x=A-B;
如果(x>0){
v=v 0){

v=v由于A和B在编译时已知,因此不仅可以消除警告,还可以消除运行时
if
,而不进行任何强制转换,如下所示:

const unsigned int x = static_cast<unsigned int>(A - B) & 0x1f; // limit A-B to have a range of (0 - 31)
#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;
}
#包括
使用名称空间std;
模板
结构我的
{
模板
静态无效移位_if(int&);
模板
静态void shift_if(int&){
模板
静态无效移位_if(int&v){v(v);}
};
模板
int foo()
{
int v=1;
我的::op(v);
返回v;
}
int main(){

cout()我相信如果右边是负数,它将把它转换成一个
无符号int
,这将使它成为正数。如果
A-B
的结果是负数,我不想运行代码。因为它在编译时知道这些值,任何大于32的数字都将标记另一个关于移位大于t的警告他输入宽度。虽然这确实解决了负号问题,但它会发出第二个警告。我将该值限制为0-32,因此不应该有警告hh,对不起,我没有读到该掩码。我以为它是在掩盖负号。更具体地说,我有
A==25
B==31
。这给了我
x==-6
看起来像是
111…11010
,截断它仍然会给我一个相当大的数字一个非常好的解决方案。尽管它需要调整以解决(a-B>=32)问题。顺便说一句,if可能会被分解掉,因为编译器可以检测到它永远不会发生。@Evan Teran,谢谢!我注意到移位换行问题,但OP的原始代码让它换行,所以我认为这是他想要的。我怀疑你关于编译器优化的说法是正确的,但在我的版本中,表达式A-B是无符号的,因此避免了理想情况下,如果这个数字是正数,我希望代码警告我移位过多,如果是负数,代码根本不会警告我(因为它不会被执行).我想只有这样才能解决这个问题。很高兴知道。你可以通过声明,而不是定义额外的专门化,使过度的正移位成为一个错误。