我刚刚从VC++ 14.0 (2015) 编译器中的错误中学到了?不应该假设结构的布局将如何在内存中结束。但是,我不明白在我见过的很多代码中这是多么普遍的做法。例如,Vulkan 图形 API 执行以下操作:
定义一个结构
struct {
glm::mat4 projection;
glm::mat4 model;
glm::vec4 lightPos;
} uboVS;
然后填写其字段:
uboVS.model = ...
uboVS....
然后只需通过 memcpy 将结构(在主机内存中)复制到设备内存:
uint8_t *pData;
vkMapMemory(device, memory, 0, sizeof(uboVS), 0, (void **)&pData);
memcpy(pData, &uboVS, sizeof(uboVS));
vkUnmapMemory(device, memory);
然后到 GPU,它定义了一个 UBO 来匹配该结构:
layout (binding = 0) uniform UBO
{
mat4 projection;
mat4 model;
vec4 lightPos;
} ubo;
然后,在 GPU 方面,ubo 将始终匹配 uboVS。
这是相同的未定义行为吗?该代码是否依赖于完全按照定义布局的 uboVS 结构,或者对于双方(编译的 C++ 代码和编译的 SPIR-V 着色器)基本上生成相同的不同结构布局?(类似于https://www.securecoding.cert.org/confluence/display/c/EXP11-C中的第一个示例。+Do+not+make+assumptions+regarding+the+layout+of+structures+with+位域)
这个问题并不特定于 Vulkan 或图形 API,我很好奇人们究竟可以假设什么以及何时可以将结构用作一块内存。我了解结构打包和对齐,但还有更多吗?
谢谢