3

序言:我想将指针转换为整数类型,例如检查对齐。uintptr_t似乎是正确的类型,但它只在 C 中得到保证,而不是在 C++(或 C++11)中

对于以下代码:

#include <stdint.h>
#ifndef I_WONDER_IF_UINTPR_T_IS_DEFINED
  typedef unsigned long uintptr_t;
#endif

template <typename T>
bool isAligned(unsigned char* p) ///Checks alignment with respect to some data type
{
   return !((uintptr_t) p % sizeof(T));
}

template bool isAligned<uint16_t>(unsigned char* p);
template bool isAligned<uint32_t>(unsigned char* p);
template bool isAligned<uint64_t>(unsigned char* p);

2个问题:

  • 是否有一个神奇且有保证的词可以在我放置的地方使用I_WONDER_IF_UINTPR_T_IS_DEFINED
  • 我应该使用unsigned long并忘记它吗?

生成的程序集(当 uintptr_t 可用时):http: //goo.gl/4feUNK

注 1:我知道在 C++11 中我应该使用alignof它来代替sizeof
注 2:我知道这个讨论:<cstdint> vs <stdint.h>

4

3 回答 3

1

一般来说,*nix 上的可移植构建系统倾向于使用“autotools”方法,即测试编译一个包含相关类型的简单文件,如果它编译,你就知道你有那个类型。如果您想要更简单的东西,您可以(a)假设uintptr_t即使在 C++ 中也可用(可能是合理的),或者(b)使用unsigned long long然后:

static_assert(sizeof(unsigned long long) >= sizeof(void*), "oops");
于 2014-10-02T11:48:21.880 回答
1

uintptr_t如果您真的想使用在 include时不提供的实现<stdint.h>,请考虑使用uintmax_t代替,以及 a static_assertfor suitability(您已经确定您可能处于愚蠢的设置中,所以它可能太小了):

#include <stdint.h>
static_assert(sizeof(uintmax_t) >= sizeof(void*), "need a bigger unsigned type.");

// Add code using `uintmax_t` to round-trip data-pointers here

不过有两个缺点:

  1. uintmax_t可能uintptr_t对重载解析和链接不重要。
  2. uintmax_t可能比必要的大。
于 2014-10-02T11:56:51.933 回答
1

我知道这已经很老了,但是,UINTPTR_MAX为你的使用怎么样I_WONDER_IF_UINTPR_T_IS_DEFINED

于 2018-06-21T09:37:38.250 回答