通过负面警告消除gcc偏移
Getting rid of gcc shift by negative warning
我有一些代码看起来像:
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将抱怨x对于A、B的某些实例化是负的;然而,我确实会进行检查,以确保它不是阴性的。最好的办法是什么?我知道我可以将x
强制转换为unsigned int
,但这将导致关于x
大于v
宽度的警告(因为它将负数强制转换为正数)。我知道有一项工作需要创建一个新的模板化shift
函数,但如果可能的话,我希望避免这种情况。
由于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;
}
为什么不将x设为无符号字符类型并进行强制转换?你肯定不需要移位超过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)
编辑:
作为对评论的回应,这里有一个想法:
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)
编辑:作为对最新评论的回应,此代码在编译时不会发出任何警告: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;
}
这样行吗?
const short unsigned int x = A - B;
它所截取的比特比需要截取的要多得多,但如果你的a-B值足够小。。。
相关文章:
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- 奇怪的结构&GCC&clang(void*返回类型)
- GCC本机矩阵运算库
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- PowerPC ppc64le上的Gcc Woverloaded虚拟错误
- gcc和c++17的过载解析失败
- 数据成员SFINAE的C++17测试:gcc vs clang
- GCC对可能有效的代码抛出init list生存期警告
- C / C++ 移位/偏移/向左或向右移动位图?
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 使用 GCC 卸载的 OpenMP 卸载失败,并出现"Ptx assembly aborted due to errors"
- 为什么与常规GCC不同,即使有"学究性错误",MinGW-GCC也能容忍丢失的返回类型
- 使用gcc从静态链接的文件中查找可选符号
- 普通环路未使用gcc 4.8.5自动矢量化
- 有了gcc,是否可以链接库,但前提是它存在
- 在clang++预处理器中确定gcc工具链版本
- 为什么 gcc 编译这个而 msvc 没有
- 为什么lambda在clang上崩溃而不是在gcc上崩溃
- GCC 4.4.3常量表达式错误的偏移.我应该如何解决这个问题
- 通过负面警告消除gcc偏移