是否有一种可移植的方法来了解是否在stdint.h中定义了uintptr_t?

时间:2014-10-02 11:44:46

标签: c++ c++11 stdint

前言:我想将指针转换为整数类型,例如:检查对齐方式。 uintptr_t似乎是正确的类型,但是it is guaranteed only in C, not in C++ (or 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>

3 个答案:

答案 0 :(得分:1)

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

static_assert(sizeof(unsigned long long) >= sizeof(void*), "oops");

答案 1 :(得分:1)

如果您确实希望在包含uintptr_t时使用不提供<stdint.h>的实施,请考虑改为使用uintmax_t,并考虑使用static_assert(您已经建立了可能是在一个愚蠢的设置,所以它可能太小了):

#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可能比必要的要大。

答案 2 :(得分:1)

我知道这已经很老了,但是将UINTPTR_MAX用于I_WONDER_IF_UINTPR_T_IS_DEFINED怎么样?