这是 g++ for 循环实现还是我的代码中的错误
Posted
技术标签:
【中文标题】这是 g++ for 循环实现还是我的代码中的错误【英文标题】:Is this a bug in the g++ for-loop implementation or in my code 【发布时间】:2021-01-08 12:46:02 【问题描述】:我目前正在从事一个 Vulkan 项目。我的交换链中有 2 个图像,但我的应用程序对其进行了 2 次以上的迭代。我看不出有什么问题,而且 CLion、g++ 和 clang++ 不会抛出任何警告。
std::cout << vulkanRendererInternalInfo.swapchainImageCount << std::endl;
for (uint32_t swapchainImageIndex = 0;
swapchainImageIndex < vulkanRendererInternalInfo.swapchainImageCount; swapchainImageIndex++)
std::cout << "is " << swapchainImageIndex << " < " << vulkanRendererInternalInfo.swapchainImageCount << " "
<< getTruthValue(swapchainImageIndex < vulkanRendererInternalInfo.swapchainImageCount) << std::endl;
VkImageViewCreateInfo imageViewCreateInfo = ;
imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
imageViewCreateInfo.pNext = nullptr;
imageViewCreateInfo.flags = 0;
imageViewCreateInfo.image = vulkanRendererInternalInfo.swapchainImages[swapchainImageIndex];
imageViewCreateInfo.format = vulkanRendererInternalInfo.swapchainFormat;
imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
imageViewCreateInfo.components.r = VK_COMPONENT_SWIZZLE_R;
imageViewCreateInfo.components.g = VK_COMPONENT_SWIZZLE_G;
imageViewCreateInfo.components.b = VK_COMPONENT_SWIZZLE_B;
imageViewCreateInfo.components.a = VK_COMPONENT_SWIZZLE_A;
imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageViewCreateInfo.subresourceRange.baseMipLevel = 0;
imageViewCreateInfo.subresourceRange.levelCount = 1;
imageViewCreateInfo.subresourceRange.baseArrayLayer = 0;
imageViewCreateInfo.subresourceRange.layerCount = 1;
std::cout << "a " << swapchainImageIndex << std::endl;
VULKAN_ASSERT(vkCreateImageView(vulkanRendererInternalInfo.device, &imageViewCreateInfo, nullptr,
&vulkanRendererInternalInfo.swapchainImageViews[swapchainImageIndex]))
getTruthValue
返回“True”或“False”,VULKAN_ASSERT
是检查 VkResult 的宏。前两次 VkResult 是 VK_SUCCESS,第三次 vkCreateImageView 创建分段错误。
当我使用 g++ -O3 -march=skylake -ffast-math ...
或 g++ -O3 ...
或 g++ -O1 ...
编译时
2
is 0 < 2 True
a 0
is 1 < 2 True
a 1
is 2 < 2 False
a 2
UNASSIGNED-GeneralParameterError-RequiredParameter(ERROR / SPEC): msgNum: -1711571459 - Validation Error: [ UNASSIGNED-GeneralParameterError-RequiredParameter ] Object 0: handle = 0x562a0969f6a8, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0x99fb7dfd | vkCreateImageView: required parameter pCreateInfo->image specified as VK_NULL_HANDLE
Objects: 1
[0] 0x562a0969f6a8, type: 3, name: NULL
VUID-VkImageViewCreateInfo-image-parameter(ERROR / SPEC): msgNum: 315335852 - Validation Error: [ VUID-VkImageViewCreateInfo-image-parameter ] Object 0: handle = 0x562a089cb8a0, type = VK_OBJECT_TYPE_INSTANCE; | MessageID = 0x12cba4ac | Invalid VkImage Object 0x0. The Vulkan spec states: image must be a valid VkImage handle (https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#VUID-VkImageViewCreateInfo-image-parameter)
Objects: 1
[0] 0x562a089cb8a0, type: 1, name: NULL
Segmentation fault (core dumped)
但是当我使用 g++ -O0 -march=skylake -ffast-math ...
或 clang++ -O3 -march=skylake -ffast-math ...
时它可以工作
【问题讨论】:
如果我删除 Vulkan API 调用,这是一个无限循环。 【参考方案1】:好吧,我想这是一个错误,因为我可以通过在 if 语句后添加 return 0;
来修复它。
【讨论】:
这些神秘错误通常是由代码中的 UB 引起的,而不是编译器错误。 是的,如果我能看到,您分享的代码包含 no @holy 来备份猫,我已经看到了 100 多个这样的错误,其中存在 UB 并且不相关的代码更改“修复”了它,并且通过这种方式最多发现了一些编译器错误,在我生命中。我什至无法猜测您为什么会看到它,因为 UB 代码有几十种不同的风格。从行人(未初始化变量、跟随死指针、缓冲区溢出等)到疯狂(ODR 违规、别名 UB 等)以上是关于这是 g++ for 循环实现还是我的代码中的错误的主要内容,如果未能解决你的问题,请参考以下文章