size_t
是实现定义的无符号整数类型。
取反一个size_t
值可能会给你一个size_t
具有通常无符号模数行为的类型结果。例如,假设size_t
是 32 位sizeof(struct foo) == 4
,则-sizeof(struct foo) == 4294967292
,或 2 32 -4。
除了一件事:一元运算-
符将整数提升(C) 或整数提升(C++)(它们本质上是同一件事)应用于其操作数。如果size_t
至少和 一样宽int
,那么这个提升什么也不做,结果是 类型size_t
。但如果int
比 宽size_t
,那么INT_MAX >= SIZE_MAX
,则 的操作数从to-
被“提升” 。在这种不太可能的情况下,.size_t
int
-sizeof(struct foo) == -4
如果您将该值分配回一个size_t
对象,那么它将被转换回size_t
,从而产生SIZE_MAX-4
您期望的值。但如果没有这样的转换,你会得到一些令人惊讶的结果。
现在我从未听说size_t
过窄于 的实现int
,因此您不太可能遇到这种情况。但这里有一个测试用例,unsigned short
用作假设的窄size_t
类型的替代,它说明了潜在的问题:
#include <iostream>
int main() {
typedef unsigned short tiny_size_t;
struct foo { char data[4]; };
tiny_size_t sizeof_foo = sizeof (foo);
std::cout << "sizeof (foo) = " << sizeof (foo) << "\n";
std::cout << "-sizeof (foo) = " << -sizeof (foo) << "\n";
std::cout << "sizeof_foo = " << sizeof_foo << "\n";
std::cout << "-sizeof_foo = " << -sizeof_foo << "\n";
}
我的系统(具有 16-bit short
、 32-bitint
和 64-bit size_t
)上的输出是:
sizeof (foo) = 4
-sizeof (foo) = 18446744073709551612
sizeof_foo = 4
-sizeof_foo = -4