Is there a portable way to know if uintptr_t is defined in stdint.h?

こ雲淡風輕ζ 提交于 2019-12-23 20:34:13

问题


Preamble: I want to convert a pointer to an integer type, e.g. to check alignment. uintptr_t seems to be the correct type, but it is guaranteed only in C, not in C++ (or C++11)

For the following code:

#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 questions:

  • Is there a magic and guaranteed word that I can use where I put I_WONDER_IF_UINTPR_T_IS_DEFINED?
  • Should I just use unsigned long and forget about it?

Generated assembly (when uintptr_t available): http://goo.gl/4feUNK

Note 1: I am aware than in C++11 I should use alignof in place of sizeof
Note 2: I am aware of this discussion: <cstdint> vs <stdint.h>


回答1:


If you really want to work with an implementation not providing uintptr_t when including <stdint.h>, consider using uintmax_t instead, and a static_assert for suitability (you already established you might be on a goofy setup, so it might be too small):

#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

There are two dis-advantages though:

  1. uintmax_t might not be uintptr_t, important for overload-resolution and linking.
  2. uintmax_t might be bigger than neccessary.



回答2:


In general, portable build systems on *nix tend to use the "autotools" approach which is to test-compile a trivial file containing the type in question, and if it compiles, you know you have that type. If you want something simpler, you could either (a) assume uintptr_t is available even in C++ (probably reasonable), or (b) use unsigned long long and then:

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



回答3:


I know this is very old, but, how about using UINTPTR_MAX for your I_WONDER_IF_UINTPR_T_IS_DEFINED ?



来源:https://stackoverflow.com/questions/26160068/is-there-a-portable-way-to-know-if-uintptr-t-is-defined-in-stdint-h

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!