Using size_t instead of uint32_t when referring to containers size.

We all have seen it, right? whenever we need some amount of certain objects, we request it to vulkan using a pointer to a uint32_t and setting to NULL the pointer to the objects we need, it is just so natural, right?, and is throughout the whole API, so the functionality is uniform. So far, so good. But my question is this: for an amount of objects, using uint32_t is correct on 32 bits only. When we move to 64 bits, the “size” of a container, of a memory request, of anything related to memory operations, becomes a 64 bits number, so i think it would be more appropriate and portable to use a size_t instead of uint32_t for such operations, the STL containers work like that.

I understand that, on the practice, rarely we will need more than the range the 32 bits have to offer, but wouldn’t there be scenarios where such operations can lead to undefined behavior just because of the diferences between uint32_t and a size_t ranges? 0xFFFFFFFFFFFFFFFF doesn’t have any meaning on a 32 bit variable, for example.

I know this is API breaking, but i wanted to leave this here merely as a thought. Have a good day!

The reason Vulkan doesn’t use size_t is precisely because it changes between 32 and 64-bit builds. Vulkan data structures and arguments should be stable, no matter what the bit-depth of the compilation is.

Also, what functions are you talking about? VkDeviceSize is used for anything dealing with sizes/offsets in device memory, and that is defined to be a uint64_t.

The only kinds of parameters which use uint32_t sizes are host-sized arrays and the number of items in pools. Neither of which is likely to need to be larger than 2^32 anytime in the near future. Are you going to create descriptor set layouts with more than 4 billion descriptors? Are you going to get more than 4 billion sparse image format properties?

So what’s the point?

pointers also change in size from 32 bit to 64 bits, and they are in every structure of the engine, pNext is a void*, and its size is 4 bytes in 32 bits and 8 bytes in 64. The idea is to enforce the proper usage of types to avoid unexpected pitfalls in the future. The STL uses size_t when it comes to the amounts of elements. I am well aware that a 64 bit integer can be something really, really, really big, but i can’t help but think that this has been somehow overlooked because we are too used to them as indexing variables.

We are used to think that to address a vector a 32 bit integer is what you have to use. But now that the 64 bit are finally settling we forget that in 64 bits the most approproate way to address a vector is to use a 64 bit variable. For example, it would help to the portability of the platform that it “typedef’ed” a “VKsize_t” type into a size_t object or something appropriate and that the whole platform stuck to that vksize_t type.

I am not requesting such a change at all though. I am just pointing out that in 64 bits things are diferent than 32 bits and that this is a subtlety that could have been passed over. Now that the platform is still “taking off” or so to say, it is a better moment to make notice of such a thing than later when it is already settled. Or who knows?

Fair enough.

But you haven’t explained what those “unexpected pitfalls” actually are.

Do you expect someone to need to make a descriptor pool that has more than 2^32 descriptors in it? Do you expect someone to need to make a query pool with more than 4 billion query objects? And so forth.

What is the actual problem that you’re trying to solve? Converting from a 64-bit unsigned integer to a 32-bit unsigned integer is a well-defined process in C/C++ if the value in that integer can fit inside 32-bits. So the only “unexpected pitfalls” that could arise is if you used a larger size than 2^32 - 1.

How would it help portability?

But the platform is settled. Vulkan 1.0 is already released; it’s not going to have an interface change until 1.1. And I highly doubt they’d bother to make changes that won’t actually improve the interface. Especially if it creates new functions that do the same thing as older ones, with the only difference being the type of the size parameter for some array.