代码之家  ›  专栏  ›  技术社区  ›  Jon Erickson

C++开发者工具:黑暗区域[关闭]

  •  9
  • Jon Erickson  · 技术社区  · 7 年前

    虽然C++标准委员会努力定义其复杂但强大的特性,并保持其与C的向后兼容性,但在我个人经验中,由于缺少工具,我发现了C++编程繁琐的许多方面。

    例如,我最近尝试重构一些C++代码,用T&替换许多SyrdYPPTR;删除大型库中不需要的指针用法。我必须手动执行几乎整个重构,因为没有任何重构工具可以帮助我安全地完成这项工作。

    使用调试器处理STL数据结构就像在陌生人不同意的时候搜出他的电话号码。

    根据您的经验,C++中缺少什么开发工具?

    12 回复  |  直到 9 年前
        1
  •  26
  •   jalf    17 年前

    我的理想工具是编译时模板调试器。它可以让我以交互方式逐步完成模板实例化,并在实例化时检查类型,就像常规调试器在运行时所做的那样。

        2
  •  11
  •   Konrad Rudolph    17 年前

    根据您的经验,C++中缺少什么开发工具?

    代码完成。认真地重构是一个很好的特性,但我认为代码完成对于API的发现性和可用性来说更基本、更重要。

    基本上,这些工具需要 任何 对C++代码的不理解。

        3
  •  8
  •   Martin Beckett    17 年前

    类方法的代码生成。当我输入声明时,你应该能够理解定义。当我在讨论这个话题时,我们能不能修正“goto声明/goto定义”总是出现在声明中?

    重构。是的,我知道这在形式上是不可能的,因为有了预处理器——但编译器在搜索和替换变量名方面仍然比我能做得更好。您还可以在语法中突出显示local、members和paramater。

    绒毛所以我刚才定义的变量是更高的?C在1979告诉我,但是2009的C++显然更喜欢我自己去发现。

    一些不错的错误信息。如果我保证永远不会在类的方法中定义一个同名的类,你保证告诉我缺少“}”吗。事实上,编译器可以有一些历史知识吗?所以如果我把一个不平衡的“{”或“()”添加到一个以前工作的文件中,我们可以考虑在消息中提到这一点吗?

    STL错误消息(很抱歉引用另一条评论)看起来不像是你读了“/dev/random”,在前面卡住了“!/bin/perl”,然后在结果中运行了税务代码吗?

    对有用的东西提出一些警告怎么样?“Integer used as bool performance warning”(整数用作布尔性能警告)没有用处,它不会对性能产生任何影响,我别无选择——这是库所做的,您已经告诉我50次了。 但如果我错过了一个”从一个类声明的结尾或者一个“}”从一个方法定义的结尾,你不会警告我——你会千方百计寻找最不可能(但理论上)正确的方法来解析结果。
    这就像浏览器中内置的拼写检查器,它乐于接受我拼写错误的wether(因为这种拼写是对阉割公山羊的一个古老术语!我写了多少次关于黑道食草动物的文章?)

    拼写检查怎么样?40年前,大型机Fortran编译器有拼写检查功能,所以如果拼写错误,第二天你就不会看到一堆卡片和一条流鼻涕的错误消息。您收到一条警告,“WRIET”已被更改为在X行中写入。现在,编译器很高兴地继续运行,并花费10分钟构建一些大型浏览文件和调试器输出,然后告诉您,您在10000行之前拼写错误。

    是的,很多这些只适用于Visual C++。

    pps。是的,他们现在带着我的药来了。

        4
  •  6
  •   CsTamas    17 年前

    如果谈到VisualStudioC++, Visual Assist 是一个非常方便的代码完成工具,一些重构——例如重命名所有/选定引用,查找/转到声明,但我仍然怀念JBuilder或IntelliJ等丰富的Java IDE。

    我仍然怀念的是一个语义差异工具——你知道,它不是逐行比较两个文件,而是语句/表达式。我在网上发现的只是一些被放弃的尝试——如果你知道,请写下评论

        5
  •  6
  •   sbi    17 年前

    C++的主要问题是解析起来很困难。这就是为什么很少有工具可以处理源代码的原因。(这也是为什么我们要处理编译器历史上最可怕的错误信息。)结果是,除了极少数例外(我只知道doxygen和VisualAssist),真正的编译器能够支持帮助我们编写和处理代码所需的一切。编译器传统上是一种非常简化的命令行工具,这是一个非常薄弱的基础来构建丰富的编辑器支持。

    大约十年来,我一直在使用VS。与此同时,它的代码完成几乎是可用的。(是的,我在双核机器上工作。否则我就不会这么说了,不是吗?)如果使用视觉辅助,代码完成实际上相当不错。如今,VS本身和VA都有一些基本的重构。这也几乎适用于它所追求的几件事(尽管它仍然明显不如代码完成)。当然,>15年的搜索和;作为盒子里唯一的工具,我的需求可能比其他语言要差得多,所以这可能没什么意义。

    然而,我真正缺少的仍然是: 在我的代码移植到的所有平台上,完全符合标准的编译器和标准库实现。 我是这么说的>上一个标准发布后10年,下一个标准发布前大约一年!(这只是补充了一点: 到2011年,C++1x被广泛采用。 )

    一旦这些问题得到解决,有几件事不时被提及,但哪些供应商仍在与a>10年前的标准(或者,就像某些功能的实际情况一样,甚至已经放弃了它),从来没有真正解决过:

    • 可用、合理、可理解的编译器消息( como 实际上相当不错,但只有当你把它和其他 C++ 编者);一个链接者不会仅仅是举手说“有些东西是错的,我不能继续”(如果你把C++作为第一语言来教,你就会明白我的意思);概念(努夫说)
    • 一个IO流实现,它不会丢掉重载带来的所有编译时优势 operator<<() 通过调用运行时解析 printf() 在幕后(Dietmar Kühl曾经打算这么做,不幸的是,他的实现在技术没有普及的情况下就夭折了)
    • 在提供丰富调试支持的所有平台上实现STL( Dinkumware 在这方面已经相当不错了)
    • 所有平台上的标准库实现都使用了本书中的每一个技巧,让我们在编译时和运行时进行更严格的检查,并获得更高的性能(yasli有过这种情况吗?)
    • 调试模板元程序的能力(是的,jalf已经提到了这一点,但不能说太多)
    • 呈现工具的编译器,如 lint 没用(不用害怕, 绒毛 供应商,这只是一厢情愿)

    如果所有这些以及我忘记提到的许多其他问题(请随意添加)都得到了解决,那么获得几乎与Java或C#并驾齐驱的重构支持将是一件好事。但只有到那时。

        6
  •  5
  •   jalf    17 年前

    试图优化编译模型的编译器。

    与其天真地根据需要包含头,在每个编译单元中再次解析它们,不如先解析一次头,为它们构建完整的语法树(这必须包括预处理器指令,因为我们还不知道定义了哪些宏),然后只要包含头,就直接运行语法树,应用已知的#定义来修剪它。

    它甚至可以被用作预编译头的替代品,因此每个头都可以单独预编译,只需将这个语法树转储到磁盘上即可。我们不需要一个单一的、容易出错的预编译头,并且在重建时会得到更细的粒度,即使头被修改,也会尽可能少地重建。

    和我的其他建议一样,这需要做很多工作才能实现,但我看不出有任何根本性的问题 不可能的 .

    它似乎可以极大地加快编译时间,使其在头文件的数量上几乎成线性,而不是在#include的数量上。

        7
  •  4
  •   fnieto - Fernando Nieto    17 年前

    一个快速可靠的索引器。大多数新奇的功能都是在这之后出现的。

        8
  •  4
  •   Martin York    17 年前

    执行编码标准的常用工具。
    采用所有通用标准,并允许您根据项目的需要打开/关闭它们。

    目前,通常只需要提供一堆perl脚本。

        9
  •  3
  •   Paul Nathan    17 年前

    我对C++工具的状态感到满意。我唯一能想到的就是在VS/gcc中默认安装Boost。

        10
  •  3
  •   Harald Scheirich    17 年前

    重构,重构,重构。在打字时进行编辑。对于重构,我至少错过了大多数现代JavaIDE所能做的一半。尽管VisualAssist X有很大的发展,但仍缺少很多重构。编写C++代码的任务仍然是如此。编写C++代码。IDE越是支持高级重构,它就越容易被构建,结构就越容易在结构上迭代和改进。拿起Intellij的演示版,然后 see what you are missing .这些只是几年前我记得的一些。

    • 提取接口:使用具有公共接口的视图类,将公共函数移到接口类(C++中,这是抽象基类),并将指定函数抽象为

    • 更好的提取方法:标记一段代码,让ide编写一个执行该代码的函数,构造正确的参数和返回值

    • 了解您正在使用的每个符号的类型,这样不仅命令完成对派生值是正确的,例如symbol->。。。但也只提供返回可在当前表达式中使用的类型的函数,例如

      ui按钮=窗口->。。。

    在。。。仅插入实际返回UiButton的函数。

        11
  •  2
  •   David Anderson    17 年前

    一个独立的工具:命名约定。

        12
  •  2
  •   jalf    17 年前

    智能智能感知/代码完成,即使是模板密集型代码。

    当你在一个函数模板中时,编译器当然什么也说不出来 当然可以 关于模板参数(至少不是没有概念),但它应该能够进行大量猜测和估计。根据类型在函数中的使用方式,它应该能够缩小可能的类型,实际上是一种保守的临时概念。如果函数中有一行调用。Foo()在模板类型上,显然必须存在Foo成员方法,Intellisense也应该在函数的其余部分建议它。

    它甚至可以查看函数从何处调用,并使用它来确定至少一个有效的模板参数类型,并在此基础上在函数内部提供Intellisense。

    如果使用 int 显然,作为模板参数,使用 int 必须是有效的,因此IDE可以将其用作函数内部的“样本类型”,并基于此提供Intellisense建议。

    JavaScript刚刚在VS中获得了Intellisense支持,这需要克服许多类似的问题,所以它可以实现。当然,考虑到C++的复杂性,这将是一个荒谬的工作量。但这将是一个很好的功能。

    推荐文章
    Jannes V  ·  Webpack URL不正确
    10 年前