I find that VkShaderModuleCreateInfo.pCode is a pointer of uint32_t instead of unsigned char or char. But what we read from SPIR-V file is binary data which are in raw bytes. So I'm wondering is there any consideration on this design? And if I cast the type of pointer to the binary data from char* to uint32_t, will there be any problem like arithmetic operations on this pointer will cause unexpected results?
Everything in SPIR-V is based on the word size of 32 bits, if values are less than 32 bits the value will be in the lower order bits of a 32 bit word. Even strings are UTF-8 octets packed 4 per word in little endian.[1]
If the shader code is not SPIR-V, then the driver will probably just cast it to some other pointer, likely a char pointer. Regardless, the buffer for pCode must still be an array of uint32_t values.[2] Depending on the system you may still need to align the buffer to some boundary, but x86 doesn't require this, and C++ requires that allocation already be aligned.
This was probably just done as a convenience to driver writers for parsing SPIR-V. If the driver needs to alias the uint32_t array to a char array (something allowed in C and C++), they're expected to handle the arithmetic on their end.