草庐IT

c++ - 有意义的诊断信息

coder 2024-02-13 原文

看了几个帖子,我觉得很多问题的出现是因为编译器/实现不会多次发出非常有意义的消息(但并非总是如此)。对于错误消息至少非常令人生畏的模板来说尤其如此。一个例子可能discussion topic

因此,我想了解几点:

a) 为什么编译器有时无法提供更有意义/有用的错误消息?是纯粹的实际原因还是技术原因,还是有其他原因。 (我没有编译器背景)

b) 为什么他们不能提供对相关符合 C++ 标准节/节的引用,以便开发人员社区可以更好地学习 C++?

编辑:

引用线程 here再举个例子。

编辑:

引用线程 here再举个例子。

最佳答案

根本问题是编译器诊断会处理您没有编写的内容。

为了给您一个有意义的错误消息,编译器必须猜测您的意思,然后告诉您您的代码与那个有何不同。

如果您缺少分号,编译器显然无法在任何地方看到该分号。当然,它可以做的其中一件事就是猜测“也许用户漏掉了一个分号。毕竟这是一个常见的错误”。但是那个分号应该放在哪里呢?因为你犯了一个错误,代码无法解析成语法树,所以没有明确的指示“树中缺少这个节点”。并且可能有不止一个地方可以插入分号,以便周围的代码能够正确解析。此外,一旦发现可能的错误,您将尝试解析/重新编译多少代码?编译器可以插入分号,但至少必须重新开始解析该代码块。但也许它在代码中进一步引入了错误。所以也许整个程序应该重新编译,只是为了确保编译器提出的修复实际上是正确的。但这也不是一个选择。时间太长了。

假设你有这样的代码:

struct foo {
 ...
}

void bar();

这里有什么错误?看着它,您和我会说“您在类定义后缺少分号”。但是编译器怎么知道呢? void 可能是错字。也许您实际上打算写一个类型为 foo 的实例的名称。那么真正的错误是它后面跟着现在看起来像函数调用的东西。

所以编译器必须猜测。 “这看起来可能是一个类定义,它后面的内容看起来像是一个类型的名称。如果是这样,则用户缺少用于分隔它们的分号”。

而且猜测并不是一门非常精确的科学。事情变得更加复杂,因为每次编译器试图变得聪明并进行猜测时,如果猜测错误,它只会增加困惑。

所以有时候,输出一条简短的消息可能会更好,只说明我们确定的内容(例如,类定义不能后跟类型名称)。这不如说“你在类定义后少了一个分号”那么有用,但如果编译器猜错了,危害会小一些。

如果它告诉您缺少分号,而错误实际上是其他原因,那只是在误导您。因此,在最坏的情况下,简洁且帮助不大的错误消息可能会更好,即使在最好的情况下它并不那么好。

编写良好的编译器错误并不容易,尤其是在像 C++ 这样困惑的语言中。 但话虽如此,一些编译器(包括 MSVC 和 GCC)可能会好得多。我相信更好的编译器诊断是 Clang 的主要目标之一。

关于c++ - 有意义的诊断信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3508628/

有关c++ - 有意义的诊断信息的更多相关文章

  1. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  4. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  5. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  6. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  7. ruby - what is - gets is a directory - 错误信息 - 2

    我遇到了这个奇怪的错误.../Users/gideon/Documents/ca_ruby/rubytactoe/lib/player.rb:13:in`gets':Isadirectory-spec(Errno::EISDIR)player_spec.rb:require_relative'../spec_helper'#theuniverseisvastandinfinite...itcontainsagame....butnoplayersdescribe"tictactoegame"docontext"theplayerclass"doit"musthaveahumanplay

  8. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

  9. += 的 Ruby 方法 - 2

    有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=

  10. ruby - 尝试比较两个文本文件,并根据信息创建第三个 - 2

    我有两个文本文件,master.txt和926.txt。如果926.txt中有一行不在master.txt中,我想写入一个新文件notinbook.txt。我写了我能想到的最好的东西,但考虑到我是一个糟糕的/新手程序员,它失败了。这是我的东西g=File.new("notinbook.txt","w")File.open("926.txt","r")do|f|while(line=f.gets)x=line.chompifFile.open("master.txt","w")do|h|endwhile(line=h.gets)ifline.chomp!=xputslineendende

随机推荐