这是 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 循环实现还是我的代码中的错误的主要内容,如果未能解决你的问题,请参考以下文章

为啥for循环遍历python中的1个项目? [关闭]

为啥我的代码会导致 java 中的堆栈溢出错误?它最终应该终止。 for循环版本不会导致错误

无限循环中的NodeJS内存消耗

Node.js/Mongoose 等待异步 For 循环

循环C ++中的分段错误Openmp

Java在方法中的for循环里写return是结束循环还是结束方法?