Почему неуправляемые дескрипторы не всегда являются uint64_t
? Почему необходимо, чтобы они были представлены как ptr
на 64-битных платформах?
#if !defined(VK_DEFINE_NON_DISPATCHABLE_HANDLE)
#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object;
#else
#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object;
#endif
#endif
В спецификации говорится
Non-dispatchable handle types are a 64-bit integer type whose meaning is implementation-dependent, and may encode object information directly in the handle rather than acting as a reference to an underlying object. Objects of a non-dispatchable type may not have unique handle values within a type or across types. If handle values are not unique, then destroying one such handle must not cause identical handles of other types to become invalid, and must not cause identical handles of the same type to become invalid if that handle value has been created more times than it has been destroyed.
Взлом со структурой и оператором вставки токена ## делает дескрипторы безопасными по типу. Вы получаете разные типы структур с разными типами дескрипторов, смешивание их в коде теперь приводит к ошибке компиляции. Вероятно, это было обнаружено как полезное спустя долгое время после того, как они использовали простой целочисленный тип в более ранних 32-разрядных выпусках, и такое изменение было трудно внести, поскольку оно может приводить к ошибкам сборки в ошибочном коде, который так или иначе каким-то образом продолжал работать. Я предполагаю, что кого-то вдохновило то, как дескрипторы объявляются другим широко используемым api.
Это просто путаница. Под капотом они обычно указатели. Я предполагаю, что они 64-битные для поддержки 64-битных платформ. Вероятно, желательно, чтобы они были одинакового размера на 32-битных платформах. Итак, 64 бита, даже если используются только 32. Поэтому они не могут быть определены как указатели на 32-битной платформе. Использование 64-битных целых чисел на 64-битной платформе, когда они на самом деле являются 64-битными указателями, может иметь некоторый тонкий недостаток. Вся суть «дескрипторов» заключается в инкапсуляции, поэтому, теоретически, вам все равно, что это за тип.
@WilliamJBagshaw Я сомневаюсь, что они используют указатели под капотом. Если внизу они выделяются из массива, то указатели могут стать недействительными после изменения размера массива. Эти, вероятно, индексы преобразованы в значения указателей.
Необязательно, чтобы они использовали указатели, только то, что они 64-битные.
Причина, по которой указатели используются, когда это возможно, заключается в том, что C и C++ не имеют строгих определений типов, поэтому использование указателей дает немного дополнительной безопасности типов, потому что вы не можете назначить VkImageView_T*
на VkImage_T*
.
Я думаю, что их идея заключалась в том, чтобы сделать так, чтобы C и C++ были 64-битными, а не встроенными типизированными. Но их идея ИМО довольно странная