禁用假“警告:左移计数> =类型的宽度” [英] disable spurious "warning: left shift count >= width of type"

查看:291
本文介绍了禁用假“警告:左移计数> =类型的宽度”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当用gcc编译一些模板代码时,我得到一个虚假的警告:左移计数> =类型宽度。

  template< int N> class bitval {
unsigned long val;
#pragma GCC diagnostic ignored-Wall
const bitval& check(){
if(N< sizeof(unsigned long)* CHAR_BIT&& val> = 1UL<<< N)){
std :: clog< val<< out of range for<< N< bits in<< std :: endl;
val& =(1UL<< N)-1; }
return * this; }
#pragma GCC diagnostic pop
};

问题是当它用N == 64实例化时, p>

现在警告是完全错误的,因为代码检查N足够大,不需要检查/掩码,所以当N为64时,移位永远不会发生。但是gcc警告。所以我试图禁用警告,但我不能弄清楚需要的#pragma魔术来关闭它...

解决方案

标签分派到救援:

  const bitval& check(){
constexpr bool enough_bits =(N using enough_bits_t = std :: integr_constant< bool,enough_bits> ;;
return check(enough_bits_t {});
}
const bitval& check(std :: false_type / * enough bits * /){
return * this;
}
const bitval&检查(std :: true_type / *足够的位* /){
if(val> =(1UL<< N)){
std :: clog< val<< out of range for<< N< bits in \\\
;
val& =(1UL<< N)-1;
}
return * this;
}

决定(有足够的位)是编译时常量,因此我计算它作为一个。



然后我构建一个类型( std :: true_type std :: false_type )基于该决定,并分派到两个不同的重载之一。



c> N 太大,不能移位,远不会被实例化,因此没有警告。如果在决策中有一个逻辑错误,代码被实例化,我得到一个编译器警告,而不是沉默(如果你设法禁用警告,并且你有一个逻辑错误,你会得到沉默的UB)。


I'm getting a spurious "warning: left shift count >= width of type" when compiling some template code with gcc:

template <int N> class bitval {
unsigned long  val;
#pragma GCC diagnostic ignored "-Wall"
    const bitval &check() {
        if (N < sizeof(unsigned long) * CHAR_BIT && val >= (1UL << N)) {
            std::clog << val << " out of range for " << N << " bits in " << std::endl;
            val &= (1UL << N) - 1; }
        return *this; }
#pragma GCC diagnostic pop
};

The problem being that when it is instantiated with N == 64, it gives the warning.

Now the warning is completely spurious, as the code checks for N being large enough that no check/mask is needed, so when N is 64, the shifts will never happen. But gcc warns anyways. So I'm trying to disable the warning, but I can't figure out the needed #pragma magic to shut it up...

解决方案

Tag dispatching to the rescue:

const bitval& check() {
  constexpr bool enough_bits = (N < sizeof(unsigned long) * CHAR_BIT);
  using enough_bits_t = std::integral_constant<bool, enough_bits>;
  return check( enough_bits_t{} );
}
const bitval& check(std::false_type /*enough bits*/) {
  return *this;
} 
const bitval& check(std::true_type /*enough bits*/) {
  if (val >= (1UL << N)) {
    std::clog << val << " out of range for " << N << " bits in \n";
    val &= (1UL << N) - 1;
  }
  return *this;
}

The decision (are there enough bits) is a compile-time constant, so I calculate it as one.

I then build a type (std::true_type or std::false_type) based off that decision, and dispatch to one of two different overloads.

So the code where N is too big to be shifted that far is never instantiated, and hence no warning. If there is a logic error in the decision, and the code is instantiated, I get a compiler warning instead of silence (had you managed to disable the warning, and you had a logic error, you'd get silent UB).

这篇关于禁用假“警告:左移计数&gt; =类型的宽度”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆