简体   繁体   English

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

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

Preamble: I want to convert a pointer to an integer type, eg to check alignment. 前言:我想将指针转换为整数类型,例如检查对齐。 uintptr_t seems to be the correct type, but it is guaranteed only in C, not in C++ (or C++11) uintptr_t似乎是正确的类型,但它仅在C中保证,而不是在C ++(或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: 2个问题:

  • Is there a magic and guaranteed word that I can use where I put I_WONDER_IF_UINTPR_T_IS_DEFINED ? 在放置I_WONDER_IF_UINTPR_T_IS_DEFINED ,我可以使用一个神奇而有保障的单词吗?
  • Should I just use unsigned long and forget about it? 我应该只使用unsigned long而忘记它吗?

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

Note 1: I am aware than in C++11 I should use alignof in place of sizeof 注1:我知道比在C ++ 11中我应该使用alignof代替sizeof
Note 2: I am aware of this discussion: <cstdint> vs <stdint.h> 注2:我知道这个讨论: <cstdint> vs <stdint.h>

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

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

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): 如果你真的想在包含<stdint.h>的情况下使用不提供uintptr_t的实现,请考虑使用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

There are two dis-advantages though: 但有两个不利因素:

  1. uintmax_t might not be uintptr_t , important for overload-resolution and linking. uintmax_t可能不是uintptr_t ,对于重载解析和链接很重要。
  2. uintmax_t might be bigger than neccessary. uintmax_t可能比必要的大。

我知道这是很老了,但是,如何使用UINTPTR_MAXI_WONDER_IF_UINTPR_T_IS_DEFINED

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM