拥有以下代码(大大简化):
#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选项添加到我的宏定义中。)
答案 0 :(得分:4)
在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
}