负大小_t

时间:2018-01-28 19:59:32

标签: c++ bit-manipulation

是否明确指定(对于一般的无符号类型):

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);
    }
}

2 个答案:

答案 0 :(得分:3)

无符号整数类型被定义为环绕,并且无符号整数类型中可表示的最高可能值是所有位设置为1的数字 - 所以是。

由于cpp-reference声明它(arithmetic operators / overflow):

  

总是执行无符号整数运算 modulo 2 n 其中n是   该特定整数中的位数。例如。对于unsigned int,   向UINT_MAX添加一个会给​0,并从0中减去一个   UINT_MAX

相关:Is it safe to use negative integers with size_t?

答案 1 :(得分:1)

  

是否明确指定(对于一般的无符号类型):

static_assert(-std::size_t{1} == ~std::size_t{0}, "!");

不,不是。

对于使用无符号类型的计算,断言必须成立。但是,此断言不保证使用无符号类型。在intsigned int应用之前,比unsigned int更窄的无符号类型将被提升为-~(取决于类型的范围)。如果它被提升为signed int,并且signed int不使用二进制补码来表示负值,则断言可能会失败。

如图所示,libstdc ++的代码不会在比int更窄的任何无符号类型中执行任何算术。 1u中的__aligned可确保每项计算都使用unsigned intsize_t,以较大者为准。这甚至适用于__space -= __diff中的减法。

至少与unsigned int一样宽的无符号类型不会进行整数提升,因此对它们的算术和逻辑运算应用于它们自己的类型,对此Johan Lundberg的答案适用:指定以模2执行< SUP>ñ