【问题标题】:Is there a gcc warning for "conditional expression is constant"?“条件表达式是常量”是否有 gcc 警告?
【发布时间】:2026-02-13 03:45:01
【问题描述】:

我继承了一个相当大的代码库,其中有人以某种方式编写了几个条件,如下所示:

enum
{
    FOO_TYPE_A,
    FOO_TYPE_B,
    FOO_TYPE_C,
    FOO_TYPE_D
};

void bar(int fooType)
{
    if (fooType == FOO_TYPE_A || FOO_TYPE_B) // <-- This will always be true, since FOO_TYPE_B is nonzero!
    {
        // Do something intended for only type A or B
    }

    // Do things general to A,B,C,D
}

条件检查应该明确在哪里:

    if (fooType == FOO_TYPE_A || fooType  == FOO_TYPE_B)

gcc中是否有警告我可以打开来找到它们,类似于MSDN的C4127

具体来说,我使用的是 Android NDK r9d。

如果不是,为什么不呢?对于无意分配、无符号 > 0 以及上述愚蠢行为,这似乎是一个有用的包罗万象。

编辑:使代码更详细以说明问题。

【问题讨论】:

标签: c++ c gcc android-ndk


【解决方案1】:

我没有看到对应于 MSDN C4127 的警告。 GCC 确实有一个意图有点相似的警告,但不是为了解决您的问题:-Wtype-limits

如果比较始终为真或始终为假,则发出警告,因为 数据类型的范围有限,但不警告常量 表达式。例如,在比较 unsigned 变量时发出警告 使用&lt;&gt;= 对抗零。此警告也由 -Wextra.

如您所见,GCC 明确声明它不会对常量表达式发出警告。这样做的动机可能是由于通常使用常量表达式来利用编译器的死代码消除,以便可以通过使用编译时间常量来优化宏(或它的一部分)。它将用作条件编译(#if defined()#if X == Y)的替代方案,因为宏读起来更自然,就像普通函数一样。作为一个假设的例子:

#define VERIFY(E) \
do { \
    if (NO_VERIFY) break; \
    if (!(E) && (VERIFY_LOG_LEVEL >= log_level() || VERIFY_LOG_ALWAYS)) { \
        log("validation error for: " #E); \
    } \
} while (0)

【讨论】:

  • 我同意默认情况下不应启用这样的假设警告,但总有一些警告会虚假触发的情况(调试版本中未使用的参数,有人吗?)。这并不意味着拥有该选项没有帮助。无论如何,这是一个尽可能好的答案,所以我会接受它。
【解决方案2】:

我认为问题在于变量是定义还是常量。 CONSTANT_2 是一个非零常数也会产生这个问题。

【讨论】:

  • 我认为他谈到|| CONSTANT_2 应该变成if(.. || 2) 在这种情况下警告可能有用
  • 对不起,我的英语很差,并且没有认真阅读这个问题。我认为问题在于变量是定义还是常量。 CONSTANT_2 是一个非零常数也会产生这个问题。
最近更新 更多