How to wrap vulkan objects in c++ code so that they can be zero-initialized without explicitly putting "{}" on declaretion?

when creating some vulkan objects like VkCommandBufferAllocateInfo,it is required to zero-initialize them first.This is error-prone,so how do I auto zero-initialize them in c++ code?

Nothing requires this. What is required is that the struct be properly initialized by the time the Vulkan implementation sees it. If “zero-initializing them first” is the only way to make your code work, that’s probably because you’re not correctly initializing all of the members.

But if you want to ensure that a basic struct is zero-initialized, you can wrap it in a type that has a default constructor which zero-initializes the member:

template<typename T>
struct zinit
{
  T value;
  zinit() value{} {}
};

This is not especially useful though. Since most Vulkan structs have an sType member that must be initialized to a specific value (as in VkCommandBufferAllocateInfo value = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO};), you’re going to have to do that manually (or write a code generator based on the Vulkan standard that creates the code for you). So there’s not much to be gained, since you need to properly initialize the object anyway.

1 Like

But I can remember I did encounter the situation in which I only forgot to put “{}” when initializing struct like VkDescriptorPoolCreateInfo,and my program crashed after that.And is that only because like what you said “because I’m not correctly initializing all of the members.”?

I used this template code in my own code,it just seems to be too cumbersome:

namespace Vk
{

	template<typename T>
	struct VkCI 
	{
		T value;
		VkCI():value{} {}
	};
	
}



Vk::VkCI<VkDescriptorPoolCreateInfo> descriptor_pool_CI;
descriptor_pool_CI.value.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;


I also notice in Sascha Willems’s vulkan example,he uses functions to do this initialization which makes code even more hard to read.

Can I just copy and paste all the structs defined in vulkan_core.h file and provide some fields of those structs with default values?What’s the pros and cons of doing this?

And thanks for your patience, Alfonse Reinheart.

I had to find a balance between too much and too little abstraction, that’s why it may not seem too intuitive for your use-case.

But there’s no need to copy what I did.

If I were to redo it, I would generate an initializer library from the Vulkan XML registry. I use that XML in different places to generate code (e.g. Vulkan Hardware Capability Viewer and the database) and it has all the info you need.

E.g.:

<type category="struct" name="VkInstanceCreateInfo">
    <member values="VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
    <member optional="true">const <type>void</type>*     <name>pNext</name></member>
    <member optional="true"><type>VkInstanceCreateFlags</type>  <name>flags</name></member>
    <member optional="true">const <type>VkApplicationInfo</type>* <name>pApplicationInfo</name></member>
    <member optional="true"><type>uint32_t</type>               <name>enabledLayerCount</name></member>
    <member len="enabledLayerCount,null-terminated">const <type>char</type>* const*      <name>ppEnabledLayerNames</name><comment>Ordered list of layer names to be enabled</comment></member>
    <member optional="true"><type>uint32_t</type>               <name>enabledExtensionCount</name></member>
    <member len="enabledExtensionCount,null-terminated">const <type>char</type>* const*      <name>ppEnabledExtensionNames</name><comment>Extension names to be enabled</comment></member>
</type>

This can easily be parsed into your own initializing stuff.

Or if you don’t mind you could always use vulkan.hpp, which does all that initialization stuff for you.

1 Like