[英]Calling derived class's methods from pointer to base class via reinterpret_casting the method pointer. Is this UB?
[英]Vulkan-hpp is reinterpret_casting non-standard-layout class to another class. Is this legal?
最近我一直在使用Vulkan-Hpp
(Vulkan Api, Github Link的官方c ++绑定)。
查看源代码,我发现它们创建了围绕本机Vulkan结构的包装类(例如vk::InstanceCreateInfo
包装VkInstanceCreateInfo
)。 ( 注意:环绕,不是来自 )
调用本机Vulkan API时,指向包装类的指针会reinterpret_cast
为原生的Vulkan结构。 使用vk::InstanceCreateInfo
的示例:
//definition of vk::InstanceCreateInfo
struct InstanceCreateInfo
{
/* member function omitted */
private:
StructureType sType = StructureType::eInstanceCreateInfo;
public:
const void* pNext = nullptr;
InstanceCreateFlags flags;
const ApplicationInfo* pApplicationInfo;
uint32_t enabledLayerCount;
const char* const* ppEnabledLayerNames;
uint32_t enabledExtensionCount;
const char* const* ppEnabledExtensionNames;
};
//definition of VkInstanceCreateInfo
typedef struct VkInstanceCreateInfo {
VkStructureType sType;
const void* pNext;
VkInstanceCreateFlags flags;
const VkApplicationInfo* pApplicationInfo;
uint32_t enabledLayerCount;
const char* const* ppEnabledLayerNames;
uint32_t enabledExtensionCount;
const char* const* ppEnabledExtensionNames;
} VkInstanceCreateInfo;
//And the usage where reinterpret_cast takes place
template<typename Dispatch>
VULKAN_HPP_INLINE ResultValueType<Instance>::type createInstance( const InstanceCreateInfo &createInfo, Optional<const AllocationCallbacks> allocator, Dispatch const &d )
{
Instance instance;
Result result = static_cast<Result>( d.vkCreateInstance( reinterpret_cast<const VkInstanceCreateInfo*>( &createInfo ), reinterpret_cast<const VkAllocationCallbacks*>( static_cast<const AllocationCallbacks*>( allocator ) ), reinterpret_cast<VkInstance*>( &instance ) ) );
return createResultValue( result, instance, VULKAN_HPP_NAMESPACE_STRING"::createInstance" );
}
所以我的问题是: vk::InstanceCreateInfo
和VkInstanceCreateInfo
是两种不同的类型。 此外, VkInstanceCreateInfo
是标准布局,但vk::InstanceCreateInfo
不是(因为它具有混合访问说明符)。 在这两种类型的指针之间(由Vulkan-Hpp
)是否合法地reinterpret_cast
? 这是否违反了严格的别名规则 ?
注意:在这种情况下,你可以假设VkInstanceCreateFlags
和vk::InstanceCreateFlags
是可以互换的(否则它会使我的问题递归)
就标准而言,是的,通过指向VkInstanceCreateInfo
对象的指针访问vk::InstanceCreateInfo
对象违反了严格别名。 即使两种类型都是具有相同布局的标准布局,它仍然会违反严格的别名。 该标准不允许您假装一个类类型是另一个类,即使它们具有相同的布局。
因此,此代码依赖于某些特定于实现的行为。
那是错的吗? 为每一个Vulkan接口函数调用做一个额外的副本会让你感觉更好,即使没有它也能工作吗? 这最终取决于你对UB的耐心程度。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.