如何处理“signed/unsigned mismatch”警告(C4018,无循环)?

How to deal with “signed/unsigned mismatch” warnings (C4018, no loop)?

这里也有类似的问题,但它们与循环索引中的特定用法有关。这是一个更通用的案例。如果没有循环怎么处理这个警告?

如何处理这个简化案例中的警告来概述问题?

int(-3) >= size_t(31)

转换至少一个操作数,使它们具有相同的符号。

将无符号转换为有符号时要小心:如果值太大,您将获得实现定义的行为。

将 signed 转换为 unsigned 时要小心 - 当原始值为负时的行为是精确定义的,但它可能会令人惊讶。如果表达式重写为 size_t(-3) >= size_t(31) 那么它总是 true.

请注意,在示例中转换为 int 是没有意义的 - 文字 3 必须是 int 类型,并且将一元 - 应用于它会给出int 结果。

这是个案分析的基础,您只需要根据您对要解决的问题的了解来做出决定。目标是避免运行时出现逻辑错误,而不是消除警告消息。

将一个或另一个值强制转换为与另一个相同的值会消除警告,但不会防止由于逻辑错误导致的运行时问题。

例如如果您有一个 large 无符号值并将其转换为有符号值,那么它会翻转为负值,这会扰乱比较。相反,将 -3 翻转为 unsigned 会使它变成一个非常大的正值,这会弄乱你正在尝试的比较。当然,显式转换值可以避免这些消息,但这些消息警告您程序可能出现意外行为,您需要仔细考虑这些变量可能采用的值。

要获得哪个值更大的答案,请使用带符号的任意算术类型,例如 boost::cpp_int

auto v1 = int(-3);
auto v2 = size_t(31);
boost::cpp_int(v1) >= boost::cpp_int(v2);

如果您可以访问 80 位 MMX 寄存器,那么请考虑使用它们来存储两个有符号的值并进行比较。