-Wtype-限制尝试限制无符号整数

-Wtype-limits on attempt to limit an unsigned integer

本文关键字:无符号整数 -Wtype-      更新时间:2023-10-16

请考虑以下示例:

unsigned short c = // ...
if (c > 0xfffful)
c = 0xfffful;

由于unsigned short实际上可以大于 16 位,因此我想在以十六进制格式将其snprintf为固定大小的缓冲区之前限制该值。

但是,GCC(但不是叮当声)给出了警告:comparison is always false due to limited range of data type [-Wtype-limits]

是 GCC 中的错误还是我错过了什么?我知道在我的机器上unsigned short正好是 16 位,但在其他平台上不能保证如此。

我会说这不是一个错误。GCC声称if (c > 0xfffful)永远是假的,这在你的机器上是真的。GCC足够聪明,可以抓住这一点,而Clang则没有。干得好海湾合作委员会!

另一方面,GCC不够聪明,没有注意到虽然它在你的机器上总是假的,但在别人的机器上不一定总是假的。加油!

请注意,在 C++11 中,*_least##_t类型出现(我保留被证明错误的权利!)由 typedef 实现。当GCC运行时,它的警告检查可能不知道原始数据类型uint_least16_t。如果是这种情况,编译器将无法推断比较在其他系统上可能是正确的。更改 GCC 以记住原始数据类型可能非常困难。我不是在为海湾合作委员会的天真警告辩护,而是在建议为什么它可能很难解决。

我很想知道海湾合作委员会的人对此有何评论。您是否考虑过向他们提出问题?

这似乎不是一个错误(也许它可以被认为是一个有点幼稚的功能),但我明白为什么你想要这段代码来实现可移植性。

在没有任何标准宏来告诉您平台上类型的大小(并且没有任何宏)的情况下,我可能会在我的构建过程中有一个步骤来解决它并将其作为-D定义传递给您的程序。

例如,在制造中:

if ...
CFLAGS += -DTRUNCATE_UINT16_LEAST_T
endif

然后:

#ifdef TRUNCATE_UINT16_LEAST_T
if (c > 0xfffful)
c = 0xfffful;
#endif

Makefile条件基于configure中步骤的输出,或者执行其他一些C++程序,该程序只是打印出sizeofs。 可悲的是,这排除了交叉编译。

从长远来看,我建议向 GCC 人员建议更智能的行为,以便在使用这些特定类型的别名时。