【问题标题】:C++ gcc vs visual c++C++ gcc 与 Visual C++
【发布时间】:2015-04-24 22:57:24
【问题描述】:

大家好,作为 C++ 的初级程序员,我正在研究编译器的一些差异我为 gcc 编译器(代码块)和 Visual C++(Visual Studio Express)导入了相同的源文件,我发现了一些奇怪的行为,我没想到。

Visual C++ 抛出了一堆在我看来相当大的错误......比如使用不同的迭代器迭代向量,迭代器来自向量的另一个实例,而不是使用这个迭代器完成的操作...... gcc 编译成功并且在运行时没有抛出错误......而可视化 c++ 在编译中抛出了一堆错误,然后抛出了“不同迭代器类型”的运行时错误,或者使用 new char[str.length()+ 进行动态字符分配1] 和 strcpy_s() 从字符串中插入它们 - 可视 C++ 调试器抛出损坏堆的运行时错误,而代码块调试器运行得很好。

我的问题是。这些编译器和调试器真的有这么大的区别吗?如果代码在 gcc 和代码块调试器上运行完全完美,但在 Visual Studio 中抛出错误,我是否应该担心我的编程处于糟糕的水平?

我学会了在代码块中使用 c++ 编程,visal c++ 向我展示了我完全不知道的错误..

【问题讨论】:

  • 在 C++ 中,即使是一个小错误也可能在编译时崩溃为“大量错误”。修复单个字符,您就可以在更大的项目中摆脱数兆字节的错误日志。如果您的代码使用 CodeBlocks 编译得很好,您不必太担心,这只是 VisualStudio 中的错误配置。通常最好坚持使用简单且免费的编译器(如 gcc),直到您开始“感受”正在发生的事情。
  • @ddinchev:我非常不同意,其中许多是未定义的行为 - 错误 - 在他的代码中 CodeBlocks 假装很好,Visual Studio 正在检测。
  • 这是未定义行为的本质,​​它不一定将自己表现为可观察到不良或意外行为。 VC++ 运行时在调试版本中比 g++ 做的错误检查更多。很高兴 VC++ 教会了你一些教训并记住它们——你的 g++ 构建同样被破坏,你注意到只是时间问题。

标签: c++ visual-studio-2010 visual-c++ gcc compiler-errors


【解决方案1】:

问题在于您的代码,而不是您的编译器或设置。您所描述的问题类型是由相当糟糕的编程或编码技术导致的未定义行为的示例(事实上,其中一些是相当难以实现的,而无需特意编写非常有缺陷的代码)。

问题是,编译器不需要检测这些东西。他们是否这样做是编译器或库实现质量的问题。在您的情况下,您的 VC++ 版本似乎正在检测 g++ 没有的问题,这是支持 VC++ 的一点。

我的经验实际上正好相反:我发现 g++ 比 VC++ 检测到的问题更多。但是,VC++ 和 g++ 都可以诊断出另一个不能诊断的问题。

这一切都表明你的里程会有所不同。就个人而言,我主张尽可能通过多个编译器提供我的所有代码 - 正是因为这扩大了诊断问题的范围。

然后我执行了一项策略,确保我的代码与所有编译器一起干净地编译(根本没有诊断,包括没有警告),而不必禁用任何诊断,并避免使用任何旨在抑制编译器诊断的代码结构.

需要意识到的一点是,编译器在安装时通常被配置为不会产生很多诊断。造成这种情况的原因是历史性的。需要打开设置,使编译器给出警告或错误。使用 g++,-Wall -pedantic 之类的命令选项(可以通过 Code::Blocks 启用)确实增加了报告的问题数量。 VC++ 也有类似的选项(虽然我不记得它们了)。

【讨论】:

  • 好的,谢谢您的回复,我不会说我的代码的问题出在编译器设置中...听起来不是那样...我只是好奇 g++ 是否应该或者不应该检测到与 vc++ 相同的错误。代码中的所有错误都很重要,但它们在我不知道的情况下就在那里......就像从向量中擦除但没有将迭代器设置为擦除函数返回的迭代器等等......,只有heapalloc 错误是个大问题,只是分配的空间较小,所以最后一个符号没有存储在数组中。
【解决方案2】:

MSVC 为std::vector 提供了“检查迭代器”,它执行了许多有用的检查。您可以通过使用-D_GLIBCXX_DEBUG 编译在 GCC 中打开其中一些类型的检查。如果您希望始终检查您的访问权限,则需要使用std::vector::at()。通常,出于性能原因,最好确保在循环之外进行边界检查,然后在循环中使用未经检查的迭代器或索引。

【讨论】:

    【解决方案3】:

    GCC 的标准库完全按照您的要求执行,包括错误和所有问题。大多数情况下,它的行为与您预期的一样,并且您没有意识到存在错误。不要被程序似乎工作的事实所迷惑,它可能仍然存在错误。

    Visual Studio 有两个标准库变体。在发布版本中,它的作用与 GCC 相同。它完全按照你告诉它做的事情,错误和所有。在 Debug 构建中,它会在幕后添加 ton 代码来检测其中一些错误,并会通知您,正如您所观察到的那样。 修复这些!。请注意,其中一些,例如“堆损坏”意味着它检测到 几秒钟前发生了错误,并且 not 是否意味着该错误处于空闲/删除状态.您还应该转到项目属性,并在 C++/General 中,确保您的警告级别设置为 Level3 甚至是 Level4。这将在编译时发现更多错误。

    编译器在这方面的差异并不显着,除了在 Debug 版本中,Visual Studio 添加了大量用于查找错误的错误检查。其他实现以及发布版本中的 Visual Studio 不会竭尽全力帮助您查找错误。

    【讨论】:

    • 区别在于默认情况下进行了多少检查。如果您要求,GCC 将添加检查(-D_GLIBCXX_ASSERTIONS-D_GLIBCXX_DEBUG-fsanitize=undefined-fsanitize=address 等)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-10
    • 2016-08-07
    • 2019-07-27
    • 1970-01-01
    • 1970-01-01
    • 2010-09-17
    相关资源
    最近更新 更多