对 unsigned int 进行一元运算的编译器警告

发布于 2024-10-04 08:32:47 字数 313 浏览 6 评论 0原文

我有这个示例代码,它生成以下警告(带 SP1 的 VS2008 编译器):

警告 C4146:一元减运算符 应用于无符号类型,结果仍然 未签名

Code:

void f(int n)
{
}

int main()
{
    unsigned int n1 = 9;
    f(-n1);
}

但是由于函数 f 将其参数作为 int ,因此这段代码不应该在没有任何警告的情况下进行编译吗?

I have this sample code which generates the following warning (VS2008 compiler with SP1):

warning C4146: unary minus operator
applied to unsigned type, result still
unsigned

Code:

void f(int n)
{
}

int main()
{
    unsigned int n1 = 9;
    f(-n1);
}

But since function f is taking it's parameter as an int shouldn't this code compile without any warnings?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

甜味拾荒者 2024-10-11 08:32:47

如果 xunsigned int 类型,那么 -x 也是这样,它实际上相当于 2n-x (其中 n 最有可能是 32)。为了避免警告并获得正确的行为,请强制转换为 int:

f(-static_cast<int>(n));

我建议阅读 C++ 标准的“表达式”一章。您将看到,在表达式 -x 中,整型提升发生在 x 上,这意味着几乎所有内容都会提升为 int,但是unsigned int 不是。

看看这个非常有趣的例子:

template<class T>
void f(T x)
{
  //somehow print type info about x, e.g. cout << typeid(x).name() or something
}

int main()
{
  char x;
  f(x);
  f(+x);
  f(-x);
}

prints:

char
int 
int

But char -> int 是整数提升,而 unsigned int -> int 是一个转换

if x is of type unsigned int, then so is -x and it is virtually equivalent to 2n-x (where n is most likely 32). To avoid the warning and get correct behavior, cast to int:

f(-static_cast<int>(n));

I would recommend reading the "Expressions" chapter of the C++ standard. There you'll see that in the expression -x integral promotions take place on x, which means that almost anything gets promoted to int, but unsigned int is not.

Look at this very interesting example:

template<class T>
void f(T x)
{
  //somehow print type info about x, e.g. cout << typeid(x).name() or something
}

int main()
{
  char x;
  f(x);
  f(+x);
  f(-x);
}

prints:

char
int 
int

But char -> int is an integral promotion, whereas unsigned int -> int is a conversion

单身狗的梦 2024-10-11 08:32:47

标准5.3.1/7

一元 - 运算符的操作数
应具有算术或枚举
类型,结果是
它的操作数。积分推广是
对积分或枚举执行
操作数。无符号数的负数
数量是通过减去来计算的
它的值来自 2n,其中 n 是
提升的位数
操作数。结果的类型是
提升操作数的类型。

还有关于积分促销4.5/1的段落

char 类型的右值,有符号 char,
unsigned char、short int 或 unsigned
短整型可以转换为
如果 int 可以,则为 int 类型的右值
代表源的所有值
类型;否则,源右值可以
转换为类型的右值
无符号整数。

即 unsigned int 不会被提升为 int。

Standard 5.3.1/7

The operand of the unary - operator
shall have arithmetic or enumeration
type and the result is the negation of
its operand. Integral promotion is
performed on integral or enumeration
operands. The negative of an unsigned
quantity is computed by subtracting
its value from 2n, where n is the
number of bits in the promoted
operand. The type of the result is the
type of the promoted operand.

And the paragraph on Integral Promotion 4.5/1

An rvalue of type char, signed char,
unsigned char, short int, or unsigned
short int can be converted to an
rvalue of type int if int can
represent all the values of the source
type; otherwise, the source rvalue can
be converted to an rvalue of type
unsigned int.

i.e. an unsigned int will not be promoted to an int.

一身骄傲 2024-10-11 08:32:47

参数是按值传递的。在函数调用 f(-n1) 中,在将参数传递给函数之前应用运算符。因此发出警告。

The parameter is pass by value. In the function call, f(-n1), the operator is applied before passing the parameter to the function. Hence the warning.

情魔剑神 2024-10-11 08:32:47

编译器警告您,将一元减号应用于无符号 int 是一件不寻常的事情,并且可能不会给出您期望的结果。如果您使用的是 32 位编译器,则在这种情况下获得的结果将相当于调用 f(4294967287u)。

The compiler is warning you that applying unary minus to an unsigned int is an unusual thing to do and may not give the result you expect. The result you get in this case will be equivalent to calling f(4294967287u) if you are using a 32-bit compiler.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文