【问题标题】:Ignore dead code warnings in C/ C++忽略 C/C++ 中的死代码警告
【发布时间】:2018-01-11 14:38:36
【问题描述】:

具有以下代码(大大简化):

#define DO_SOME_STUFF(val,x,y) \
  if (x>y) \
  { \
    val = val >> (x-y); \
  } else { \
    val = val >> (y-x); \
  }

使用扩展调用宏的示例如下:

 int val = 5;
 DO_SOME_STUFF(val,5,10);
 => 
 if (5>10)
 {
   // dead code
   val = val >> (5-10); // negative shift warning here
 } else {
   // live code
   val = val >> (10-5); // valid code
 }

现在,既然有死代码,它会被编译器删除,每个人都会很高兴,因为我永远不会负转移 - 所以我在这里做合法的事情。

不幸的是,我在删除代码之前收到了警告(或者看起来如此)。

在我正在工作的项目中,该函数将被调用 100 多次,到目前为止我想出的唯一解决方案是执行以下操作:

#pragma GCC diagnostic ignored "-Wshift-count-negative"
DO_SOME_STUFF(val,300,20);
#pragma GCC diagnostic pop

这不是很好,因为我会添加大量这些会导致难以阅读的蓝色代码,如果可能的话我宁愿避免它。

是否有一种优雅的方法可以删除仅针对我的宏扩展的警告或要求编译器忽略死代码? (不幸的是,我无法将#pragma 选项添加到我的宏定义中)。

【问题讨论】:

  • 这就是改用函数的原因之一..
  • 您是坚持使用 C 宏还是可以接受纯 C++ 解决方案?
  • 摆脱宏。绝对没有理由在这里拥有一个。
  • 如果你用staticstatic inline 声明函数,它可能会得到同样的优化。
  • @MichaelCMS 我不会这么认为。使用函数检查生成的程序集并进行全面优化。完全有可能函数被内联并且无法访问的分支(以及分支条件本身)被优化。它会在没有任何警告的情况下做到这一点。

标签: c++ c macros preprocessor


【解决方案1】:

在 c++11 中,您可以使用模板 constexpr 函数代替宏。然后可以在编译期间执行,不会产生警告。

template <typename T, typename T2>
constexpr T do_some_stuff(const T& val, const T2& x, const T2& y)
{  
  return x > y ? val >> (x - y) : val >> (y - x);
}

template <typename T, typename T2>
constexpr T do_some_stuff_wrong(const T& val, const T2& x, const T2& y)
{  
  return x < y ? val >> (x - y) : val >> (y - x);
}

int main() 
{
    constexpr int val = do_some_stuff(5, 5, 10); // no warning
    constexpr int val2 = do_some_stuff_wrong(5, 5, 10); // warning
}

Live example

【讨论】:

  • 谢谢。实际上想知道C ++版本。现在我需要的只是 C 版本的答案(不幸的是,这是我现实生活中的问题)。
  • 如果是 C 问题,为什么要标记 C++?
  • @AndreiAndrey 因为这个问题对c++ pre c++11有效
  • @MichaelCMS 添加了一个修复程序,以使其与 c++11 一起使用。是的,存在第二个限制。
  • @usr2564301 它没有。但是,它显示了对我的问题的解释的有效答案。答案并不完整,因为它也不适用于 C++ pre 11,这就是它不被接受的原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-21
  • 1970-01-01
  • 2011-04-03
  • 2015-01-05
相关资源
最近更新 更多