0

私は次の機能を持っています:

size_t calc_allign(size_t num) {
    return ((num + 7) & (-8)) - num;
}

そして、次のように使用したい:

int start_allign = calc_align (sbrk(0));

しかし、私はエラーが発生しています:

error: no matching function for call to 'calc_align'
candidate function not viable: cannot convert argument of incomplete type 'void *' to 'size_t' (aka 'unsigned long') for 1st argument
size_t calc_align(size_t num) {

void*ポインタを数値に変換するにはどうすればよいですか? それは合法的なものですか?

4

1 に答える 1

1

void*、つまりポインターを数値に変換するにはどうすればよいですか?

(または符号付きの同等物)reinterpret_castへのポインター型を指定できます。std::uintptr_tその後、 などの別の整数型にさらに変換std::size_tでき、その変換は暗黙的に行うことができます。理論的には、後者の変換std::size_tは、より小さなタイプのシステムでは損失が大きくなる可能性があります。

ただし、C++ 言語に関する限り、結果の数値std::uintptr_tを同じポインター型に変換した場合に同じポインター値になるという保証はありません。

さらに、いくつかのコードを表示できますか?

例:

void* ptr = sbrk(0);
auto numptr = reinterpret_cast<std::uintptr_t>(ptr);
static_assert(sizeof(std::size_t) >= std::uintptr_t,
    "Sorry, it isn't possible to represents pointers using std::size_t on this system");
std::size_t example = numptr;

auto ptr2 = reinterpret_cast<void*>(numptr);
assert(ptr2 == ptr); // guaranteed to pass

reinterpret_cast が (uintptr_t) でないのはなぜですか?

C スタイルのキャストとも呼ばれる明示的な変換の動作は、オペランドの型によって異なります。安全でないキャストもあれば、良性のキャストもあります。多くの場合、単純なミスにより、意図した安全なキャストが意図せずに安全でなくなり、未定義の動作につながります (これは非常に悪いことです) - 一方、適切な C++ スタイルのキャストはコンパイル エラーになり、間違いの検出につながります (これは非常に良いことです)。

reinterpret_cast の場合、このような安全でないキャストを行っているため、安全面はありませんが、代わりに C++ スタイルのキャストの重要性は、安全性の欠如をプログラムの読者に伝えることです。

C++ で C スタイルのキャストを使用しないでください。あなたは何のためにそれらを必要としません。

于 2021-07-02T07:59:03.817 に答える