[英]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
,尽管我在变量的初始化时使用了一元减运算符。 为什么只考虑sizeof
( std::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是提升的操作数中的位数。 结果的类型是提升的操作数的类型。
sizeof
和sizeof...
的结果是std::size_t
类型的常量
要避免实现定义的行为,您必须在应用之前转换为int
-
如果目标类型已签名,则该值如果可以在目标类型中表示,则不会更改; 否则,该值是实现定义的。
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.