C++ 避免对未使用的代码部分发出警告

C++ avoid warning on non-used code parts

我想在复杂系统中使用代码部分,它等同于以下内容:

static constexpr int abits = 13;
static constexpr int bbits = 10;

...

int atob(int a) {
    if ( abits == bbits ) return a;
    else if ( abits > bbits ) return a >> (abits-bbits);
    else return a << (bbits-abits);
}

abitsbbits 可能会随时间变化(当然是在编译时)。最终代码中始终只编译了一行,即使在调试模式下也是如此。但是,我收到一条关于移动负值的警告消息。

我使用 GCC 7.3.0,不想避免所有关于负偏移值的警告。我想摆脱对根本不使用的代码的警告。但是,我没有找到它的开关。

如果您的条件是 constexpr,您可以在编译时使用 constexpr if 进行分支。

static constexpr int abits = 13;
static constexpr int bbits = 10;

int atob(int a) {
    if constexpr ( abits == bbits ) return a;
    else if constexpr ( abits > bbits ) return a >> (abits-bbits);
    else  return a << (bbits-abits);
}

constexpr if 是一个 c++17 特性,它在 gcc 7.3.0 上可用 -std=c++17 标志。

编辑:C++14 解决方案可以使用 std::enable_if。诀窍是为三种情况提供重载,只启用适用的一种。

static constexpr int abits = 13;
static constexpr int bbits = 10;

#include <type_traits>

template<int I>
std::enable_if_t<I == 0, int> 
atob_impl(int a) {
    return a;
}

template<int I>
std::enable_if_t<(I > 0), int> 
atob_impl(int a) {
    return a >> (abits-bbits);
}

template<int I>
std::enable_if_t<(I < 0), int> 
atob_impl(int a) {
    return a << (bbits-abits);
}

int atob(int a) {
    return atob_impl<abits - bbits>(a);
}

由于您使用的是 GCC 7.3.0,它支持带有 -std=c++17 的 C++17,您可以使用 if constexpr:

消除此警告
int atob(int a) {
    if constexpr ( abits == bbits ) return a;
    else if constexpr ( abits > bbits ) return a >> (abits-bbits);
    else return a << (bbits-abits);
}

Demo


一般来说,通常有一种方法可以在代码中抑制警告(也就是说,没有 #pragmas 来禁用警告)。 (void)variable; 可以抑制未使用的变量警告,if 中的赋值可以通过添加额外的括号 (if ((thing = value))) 等来抑制

在这种情况下,您可以使用 std::max:

来抑制警告
else return a << std::max(0, bbits-abits);

由于 bbitsabitsconstexpr,编译器将对 std::max 调用进行常量折叠并产生直接结果(假设编译时进行了优化)。

Demo

我想经典的 C 解决方案不适合 C++,但它存在:您可以使用

#define abits 13
#define bbits 10

int atob(int a) {
#if abits == bbits
    return a;
#elif abits > bbits
    return a >> (abits-bbits);
#else
    return a << (bbits-abits);
#endif
}