C++ visualc&x2B+;-为什么要麻烦调试模式?

C++ visualc&x2B+;-为什么要麻烦调试模式?,c++,visual-studio,debugging,release-mode,C++,Visual Studio,Debugging,Release Mode,因此,我刚刚遵循了在启用调试符号、禁用优化以及发现断点在符号符合发布模式时起作用之后的建议,我发现自己在想 调试模式的目的不是帮助您查找bug吗 如果调试模式让bug从你身边溜走,为什么还要麻烦呢 任何建议?优化将被关闭,这使得调试更容易(否则代码可能会以奇怪的方式重新排序)。还可以包括条件代码,如assert()等。由于优化程序而导致的错误并非闻所未闻;但通常情况下,它们暗示了一个更深层次的问题,例如,在需要时不使用volatile,将导致Optimizer bug(优化比较并使用缓存结果)

因此,我刚刚遵循了在启用调试符号、禁用优化以及发现断点在符号符合发布模式时起作用之后的建议,我发现自己在想

  • 调试模式的目的不是帮助您查找bug吗
  • 如果调试模式让bug从你身边溜走,为什么还要麻烦呢

  • 任何建议?

    优化将被关闭,这使得调试更容易(否则代码可能会以奇怪的方式重新排序)。还可以包括条件代码,如assert()等。

    由于优化程序而导致的错误并非闻所未闻;但通常情况下,它们暗示了一个更深层次的问题,例如,在需要时不使用
    volatile
    ,将导致Optimizer bug(优化比较并使用缓存结果)

    最后,在早期版本中包含调试符号可以帮助您在部署后跟踪bug

    现在,直接回答您的问题:

  • 调试模式还有其他功能,比如在发布模式中剥离的
    assert()
    s
  • 即使您在发布模式下进行所有测试,bug仍然会悄悄溜走。事实上,一些bug(如上面的
    volatile
    bug)只在调试模式下隐藏:它们仍然存在,只是更难触发

  • 在应用程序中包含完整符号包括有关生成机器的重要信息(嵌入路径等)

    建议在发布版本中包含“仅PDB”符号(不包括文件、行和局部变量符号),并启用优化。调试构建没有优化和完整符号

    而且(如其他答案中所述)公共子表达式消除和指令重新排序可以使调试变得有趣(下一步转到第n、n+2、n+1行…。

    除了您的应用程序在发布模式下非常易于调试之外,MSVC运行时库并不是很好,其他一些库也不是


    例如,调试堆在分配的内存周围添加无人值守标记,以防止缓冲区溢出。MSVC使用的标准库断言迭代器的有效性。还有更多。

    优化是调试的噩梦。有一次我有了一个应用程序,这个for循环

    for (int i = 0; i < 10; i++)
    {
      //use i with something
    }
    
    for(int i=0;i<10;i++)
    {
    //用我来形容某事
    }
    

    调试时我总是0。但将其输出到控制台表明它确实增加了

    事实上,没有发布模式或调试模式。只是启用了不同选项的不同配置。发布“模式”和调试“模式”只是常见的配置

    您所做的是修改发布配置,以启用调试配置中通常启用的一些选项

    启用这些选项会根据您启用的二进制文件使二进制文件变大和变慢

    您启用的这些选项越多,就越容易发现bug。我认为你的问题应该是“为什么要麻烦发布模式?”答案是它更小更快。

    调试模式不会“让bug从你身边溜走”。它插入检查以捕获大量bug,但这些检查的存在也可能隐藏某些其他bug。所有的错误检查代码都捕获了很多错误,但它也起到了填充的作用,并且可能隐藏细微的错误边界

    因此,这本身就足够让这两种模式同时运行。MSVC在调试模式下执行许多额外的错误检查


    此外,许多调试工具,如
    assert
    依赖于未定义的
    NDEBUG
    ,这在调试版本中是如此,但在默认情况下,在发布版本中不是如此。

    如果您所做的只是打印它,那么完全有可能为您的变量分配了内存,然后从未使用过,首选在寄存器中缓存
    i
    。诡计多端。你要找的词是“优化”,而不是“优化”。)“如果它让虫子从你身边溜走”是什么意思?它是如何做到的?调试模式初始化了未初始化的变量,并在数组等周围设置了防护装置,如链接文章中所述。