Attempt times:

template<typename THigh, typename TLow> inline size_t compact(THigh hi, TLow lo){ return (reinterpret_cast<size_t>(hi)<<32) | reinterpret_cast<size_t>(lo); } 

Types THigh , TLow can be a numeric type, or a pointer type in any combination. The compiler swears invalid cast on the proposed version.

Attempt two:

  template<typename THigh, typename TLow> inline size_t compact(THigh hi, TLow lo){ return (static_cast<size_t>(hi)<<32) | static_cast<size_t>(lo); } 

The compiler again swears invalid static_cast . Alteration in the macro gives absolutely nothing. You can write four functions, but their code is essentially identical.

You can use outdated c-style:

 template<typename THigh, typename TLow> inline size_t compact(THigh hi, TLow lo){ return ((size_t)(hi)<<32) | (size_t)(lo); } 

But this style hides (subtle) type casting.

In general, you need to combine all the options:

void*, size_t

size_t, void*

void*, void*

This feature is needed to convert data from MMIO with 32-bit access to 64-bit system pointers. That is, the major or minor part is a number, and the rest is a pointer. The number and the number will only be a side effect.

size_t is 64 bits wide. Pointers are 64 bits. All - 64 bits, only one parameters - numbers, and other pointers.

  • You can try to make the template function ptrToInt to convert the pointer to size_t. reinterpret_cast <size_t> (ptr) - such a cast is quite legitimate. And make your function non-template, but you have to use ptrToInt when you pass a pointer to your compact function (ptrToInt (p), int) - awesome
  • @awesome did not understand the idea. The first element can also be a number. - Adokenai
  • But tell me where does the case come from, that the pointer should be added to the number? and will there be the same meaning in the << 32 shift on the 64-bit platform? - goldstar_labs pm
  • one
    And since when are the C-style castes deprecated? What are such far-reaching statements based on? - AnT 3:21 pm
  • @AnT because of this attitude, modern software is slow, buggy and with inherent bugs. Comment refers to the question exactly as much as in any way, it lacks objectivity on the topic. There are no solutions or clarifications on the topic. - Adokenai pm

1 answer 1

 class A { }; size_t ptrToInt(void* p) { return reinterpret_cast<size_t>(p); } size_t compact(size_t h, size_t l) { return (h << 32) | l; } int main() { A* a = new A; int b = 5; size_t res = compact(ptrToInt(a), b); size_t res2 = compact(b, ptrToInt(a)); return 0; } 
  • In the 32-bit system, the older part is simply cut off - avp
  • Why is size_t used to represent a pointer? - AnT
  • one
    @AnT because the pointer can be safely placed in size_t. - awesome
  • The pointer cannot be safely placed in size_t . It is safe to place the pointer in uintptr_t , and not in size_t . - AnT
  • size_t is a synonym for uintptr_t and UINT_PTR. Can I refer to a standard where it says that size_t does not necessarily match the size of the pointer? It has been given that it can be used as a model. - awesome