如何在C++中将否定的一个写为无符号文字

dev*_*vtk 3 c++ unsigned literals

在我的程序中,我经常使用-1(也称为UINT_MAX)作为无符号变量的值来表示特殊的东西.我也比较这个值.打开更高级别的警告消息表明编译器(VS和GCC)不喜欢这种语法.

// warning C4245: 'initializing' : conversion from 'int' to 'unsigned int', signed/unsigned mismatch
unsigned a = -1;

// warning C4146: unary minus operator applied to unsigned type, result still unsigned
unsigned b = -1U;

// fine but messy
unsigned c = unsigned(-1);

// no warning on VS, signed/unsigned comparison warning with GCC
if (a == -1)
{
  std::cout << "check\n";
}
Run Code Online (Sandbox Code Playgroud)

问题1:上面给出的语法(每种情况)是合法的C++代码吗?

问题2:我是否真的必须写无符号(-1)我使用此值来分配/比较unsigned int或者是否有更简洁的方法不会触发编译器警告?

dev*_*vtk 6

答案1:

是的,它们都是正确的 C++ 构造,尽管可以说是令人不快。

  • -1被解释为 int 文字。这是正确的 C++ 语法,因为标准允许隐式 int 到 unsigned int 转换,但编译器会在更高警告级别使用此隐式转换时发出警告。
  • -1U被解释为-(1U). 对 unsigned int 取负数是正确的 C++ 语法,因为编译器会执行此运算 modulo (UINT_MAX + 1),但是编译器会发出警告让您知道。
  • (unsigned(-1) == -1)也是正确的语法,因为编译器会隐式转换-1unsigned(-1)进行比较。它确实会警告您更高警告级别的隐式转换,让您知道它已经这样做了。

答案2:

有几个选项可以unsigned(-1)作为文字写入或生效:

  • unsigned(-1)
  • Write ~0U,在二进制补码机上,取0每个位,然后取反,从而给出最大的可表示无符号数。
  • UINT_MAX将其有效地写#defineunsigned(-1)
  • 如果分配或与无符号值进行比较,请编写-1并让编译器执行隐式转换并处理警告消息。但是,应该注意的是,-1 是 int 文字,仅根据其在代码中的功能转换为无符号。
  • 编写std::numeric_limits<unsigned>::max()一个返回 的函数unsigned(-1)。请注意,在 C++11 中,此函数将是一个 constexpr,好的编译器应始终将其简化为文字。VC++ 目前将其简化unsigned(-1)为非调试构建。然而,它是从函数调用返回的值,而不是文字。


Joh*_*web 5

就其本质而言,您不能将CTA或任何其他语言中的否定文字写为无符号文字.

你不是说-1,你的意思是std::numeric_limits<unsigned int>::max().

#include <iostream>
#include <limits>

int main()
{
    unsigned a = std::numeric_limits<unsigned int>::max();

    if (a == std::numeric_limits<unsigned int>::max())
    {
        std::cout << "check " << a << "\n";
    }
}
Run Code Online (Sandbox Code Playgroud)

C++ 11标准创建了这个函数constexpr,它保证了函数是一个编译时常量.(进一步阅读).

如果您想避免使用较旧的编译器为循环的每次迭代计算此值,请在循环const外部创建并比较:

const unsigned int magic_number = std::numeric_limits<unsigned int>::max();

    // [...]
    if (a == magic_number)
Run Code Online (Sandbox Code Playgroud)

  • 它是C ++ 11中的constexpr。 (2认同)