是否明确指定(对于一般的无符号类型):
static_assert(-std::size_t{1} == ~std::size_t{0}, "!");
我只是查看 libstdc ++ 的std::align
实现,并注意使用std::size_t
否定:
inline void*
align(size_t __align, size_t __size, void*& __ptr, size_t& __space) noexcept
{
const auto __intptr = reinterpret_cast<uintptr_t>(__ptr);
const auto __aligned = (__intptr - 1u + __align) & -__align;
const auto __diff = __aligned - __intptr;
if ((__size + __diff) > __space)
return nullptr;
else
{
__space -= __diff;
return __ptr = reinterpret_cast<void*>(__aligned);
}
}
答案 0 :(得分:3)
无符号整数类型被定义为环绕,并且无符号整数类型中可表示的最高可能值是所有位设置为1的数字 - 所以是。
由于cpp-reference声明它(arithmetic operators / overflow):
总是执行无符号整数运算 modulo 2 n 其中n是 该特定整数中的位数。例如。对于
unsigned int
, 向UINT_MAX
添加一个会给0
,并从0
中减去一个UINT_MAX
。
答案 1 :(得分:1)
是否明确指定(对于一般的无符号类型):
static_assert(-std::size_t{1} == ~std::size_t{0}, "!");
不,不是。
对于使用无符号类型的计算,断言必须成立。但是,此断言不保证使用无符号类型。在int
或signed int
应用之前,比unsigned int
更窄的无符号类型将被提升为-
或~
(取决于类型的范围)。如果它被提升为signed int
,并且signed int
不使用二进制补码来表示负值,则断言可能会失败。
int
更窄的任何无符号类型中执行任何算术。 1u
中的__aligned
可确保每项计算都使用unsigned int
或size_t
,以较大者为准。这甚至适用于__space -= __diff
中的减法。
至少与unsigned int
一样宽的无符号类型不会进行整数提升,因此对它们的算术和逻辑运算应用于它们自己的类型,对此Johan Lundberg的答案适用:指定以模2执行< SUP>ñ