3

プリアンブル: ポインターを整数型に変換したい (アライメントをチェックするなど)。uintptr_t正しい型のようですが、C++ (または C++11) ではなく、C でのみ保証されています。

次のコードの場合:

#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++11alignofの代わりに使用する必要があるsizeof
ことを認識しています 注 2: この議論を認識しています: <cstdint> vs <stdint.h>

4

3 に答える 3

1

uintptr_tを含めたときに提供されない実装で本当に作業したい場合は、代わりに<stdint.h>を使用することを検討してください。uintmax_tstatic_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

ただし、2 つの欠点があります。

  1. uintmax_tではないかもしれませんがuintptr_t、オーバーロードの解決とリンクにとって重要です。
  2. uintmax_t必要以上に大きいかもしれません。
于 2014-10-02T11:56:51.933 に答える
1

一般に、*nix 上のポータブル ビルド システムは、問題の型を含む単純なファイルをテスト コンパイルする「autotools」アプローチを使用する傾向があり、コンパイルされた場合、その型があることがわかります。より単純なものが必要な場合は、(a) uintptr_tC++ でも利用できると仮定する (おそらく合理的) か、(b) 使用unsigned long longしてから:

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

私はこれが非常に古いことを知っていますが、UINTPTR_MAXあなたのために使用するのはI_WONDER_IF_UINTPR_T_IS_DEFINEDどうですか?

于 2018-06-21T09:37:38.250 に答える