【问题标题】:How does gcc handle -Wtype-limits?gcc 如何处理 -Wtype-limits?
【发布时间】:2013-04-18 09:18:12
【问题描述】:

我正在测试一个带有 gcc 4.4.5-Wtype-limits 选项的小代码 sn-p。

#include <assert.h>
#include <limits.h>
#include <stdint.h>

int main(void)
{
    /* With other values of v, the behavior of the compiler is the same. */
    uint16_t v = 0; 
    assert((unsigned int)INT_MAX < (unsigned int)v); /* l. 7 */
    return 0;
}

然后,编译器向我抛出以下警告:

main.c:7: warning: comparison is always false due to limited range of data type

但是,据我所知,INT_MAX 可能等于+32767(来自C11 (n1570),§ 5.2.4.2.1 整数类型的大小&lt;limits.h&gt;)。在这种情况下,变量v 将能够保存值INT_MAX+1,并且assert 中的表达式将被计算为1

因此,我可以看到两个问题:

  • GCC 考虑了我的架构,因为事实上INT_MAX 不等于+32767。在那种情况下,它会减少 -Wtype-limits 对我的好处。
  • 这是一个错误。

让我想到第二个选项的是以下代码,它不会产生任何具有相同选项的警告。

#include <assert.h>
#include <limits.h>
#include <stdint.h>

int main(void)
{
    assert((unsigned int)INT_MAX < (unsigned int)UINT16_MAX);
    return 0;
}

那么,正确答案是什么?

PS:顺便说一句,我必须为我的旧版本gcc道歉。也许下一个版本的行为会有所不同。

【问题讨论】:

  • 您希望 gcc 对INT_MAX 的任何可能值发出警告?另外我希望这一切都是在预处理之后完成的,所以当它检查这个警告时,它可能看到的只是变量和整数常量之间的比较。

标签: c gcc types


【解决方案1】:

GCC 确实考虑了类型的实际已知限制。它知道 int 在您的情况下超过 16 位宽,因此会发出警告。

您不会收到任何警告

#include <assert.h>
#include <limits.h>
#include <stdint.h>

int main(void)
{
    assert((unsigned int)INT_MAX < (unsigned int)UINT16_MAX);
    return 0;
}

因为标准在 7.20.2 (2) 中说:

任何已定义宏的每个实例都应替换为适合在#if 预处理指令中使用的常量表达式,并且该表达式应具有与作为转换的相应类型的对象的表达式相同的类型根据整数促销。

所以对于 32 位宽 ints,宏 UINT16_MAX 是一个 int,因此所涉及类型的限制并不能保证比较始终为假(或真)。

【讨论】:

    猜你喜欢
    • 2021-10-25
    • 2020-02-29
    • 1970-01-01
    • 2018-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多