繁体   English   中英

为什么'auto'不尊重一元减运算符?

[英]Why does 'auto' not respect the unary minus operator?

我是很新的C ++,但我觉得这种行为auto怪异:

class A{};

int main() {
    A a;
    auto x = -(sizeof(a));
    cout << x << endl;
    return 0;
}

在这种情况下,变量x是unsigned ,尽管我在变量的初始化时使用了一元减运算符。 为什么只考虑sizeofstd::size_t )的返回类型,而不是因为使用的运算符而存储的数字是否为负数这一事实?

我知道size_t是一个unsigned int。

我用GCC 8.1.0和C ++ 17试过这个。

这里的实际问题是使用一元减运算符,就像其他内置算术运算符一样,是一个整体促销的主题。 令人惊讶的是,将一元减号应用于size_t的结果仍然是size_t并且不需要责怪auto

相反的例子。 在这种情况下,由于整数提升, x类型将为int因此输出将为-1

unsigned short a{1};
auto x{-a};
cout << x << endl;

您的表达-(sizeof(a))一元适用-操作者的无符号类型的值。 一元运算符不会将无符号整数值转换为有符号整数值; 它更确定哪个无符号值将是如下操作的结果(参见cppreference.com上的一元算术运算符 ):

内置的一元减运算符计算其提升的操作数的负数。 对于无符号a,-a的值为2 ^ b -a,其中b是提升后的位数。

因此,即使它可能令人惊讶, auto也能正常工作,因为将unary - operator应用于无符号值仍然是无符号值。

(一元)的结果-应用于无符号值是无符号的,而sizeof返回无符号值。

一元运算符的操作数应具有算术或无范围的枚举类型,结果是其操作数的否定。 对整数或枚举操作数执行整体提升。 通过从2 ^ n减去其值来计算无符号数量的负数,其中n是提升的操作数中的位数。 结果的类型是提升的操作数的类型。

[expr.unary.op]

sizeofsizeof...的结果是std​::​size_t类型的常量

[expr.sizeof]

要避免实现定义的行为,您必须在应用之前转换为int -

如果目标类型已签名,则该值如果可以在目标类型中表示,则不会更改; 否则,该值是实现定义的。

[conv.integral]

class A{};

int main() {
    A a;
    auto x = -(int{sizeof(a)});
    cout << x << endl;
    return 0;
}

如果我们看一下: https//en.cppreference.com/w/cpp/language/sizeof ,结果是size_t类型,它是unsigned 您明确需要将其声明为signed int以允许负值。

您可以编写允许负值的int而不是auto

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM