If talking about MS Visual Studio C++, Visual Assist is a very handy tool for code completition, some refactorings - e.g. rename all/selected references, find/goto declaration, but I still miss the richness of Java IDEs like JBuilder or IntelliJ.
What I still miss, is a semantic diff tool - you know, one which does not compare the two files line-by-line, but statements/expressions. What I've found on the internet are only some abandoned tries - if you know one, please write in comment
The main problem with C++ is that it is hard to parse. That's why there are so very few tools out there that work on source code. (And that's also why we're stuck with some of the most horrific error messages in the history of compilers.) The result is, that, with very few exceptions (I only know doxygen and Visual Assist), it's down to the actual compiler to support everything needed to assist us writing and massaging the code. With compilers traditionally being rather streamlined command line tools, that's a very weak foundation to build rich editor support on.
For about ten years now, I'm working with VS. meanwhile, its code completion is almost usable. (Yes, I'm working on dual core machines. I wouldn't have said this otherwise, wouldn't I?) If you use Visual Assist, code completion is actually quite good. Both VS itself and VA come with some basic refactoring nowadays. That, too, is almost usable for the few things it aims for (even though it's still notably less so than code completion). Of course, >15 years of refactoring with search & replace being the only tool in the box, my demands are probably much too deteriorated compared to other languages, so this might not mean much.
However, what I am really lacking is still: Fully standard conforming compilers and standard library implementations on all platforms my code is ported to. And I'm saying this >10 years after the release of the last standard and about a year before the release of the next one! (Which just adds this: C++1x being widely adopted by 2011.)
Once these are solved, there's a few things that keep being mentioned now and then, but which vendors, still fighting with compliance to a >10 year old standard (or, as is actually the case with some features, having even given up on it), never got around to actually tackle:
usable, sensible, comprehensible compiler messages (como is actually pretty good, but that's only if you compare it to other C++ compilers); a linker that doesn't just throw up its hands and says "something's wrong, I can't continue" (if you have taught C++ as a first language, you'll know what I mean); concepts ('nuff said)
an IO stream implementation that doesn't throw away all the compile-time advantages which overloading operator<<() gives us by resorting to calling the run-time-parsing printf() under the hood (Dietmar Kühl once set out to do this, unfortunately his implementation died without the techniques becoming widespread)
STL implementations on all platforms that give rich debugging support (Dinkumware is already pretty good in that)
standard library implementations on all platforms that use every trick in the book to give us stricter checking at compile-time and run-time and more performance (wnhatever happened to yasli?)
the ability to debug template meta programs (yes, jalf already mentioned this, but it cannot be said too often)
a compiler that renders tools like lint useless (no need to fear, lint vendors, that's just wishful thinking)
If all these and a lot of others that I have forgotten to mention (feel free to add) are solved, it would be nice to get refactoring support that almost plays in the same league as, say, Java or C#. But only then.
My dream tool would be a compile-time template debugger. Something that'd let me interactively step through template instantiations and examine the types as they get instantiated, just like the regular debugger does at runtime.
代码完成。 严重地。 重构是一个很好的功能,但我认为代码完成对于 API 的可发现性和可用性来说更为基础和重要。
基本上,需要理解 C++ 代码的工具很糟糕。
In your experience, what essential developer tools are lacking in C++?
Code completion. Seriously. Refactoring is a nice-to-have feature but I think code completion is much more fundamental and more important for API discoverabilty and usabilty.
Basically, tools that require any undestanding of C++ code suck.
Code generation of class methods. When I type in the declaration you should be able to figure out the definition. And while I'm on the topic can we fix "goto declaration / goto definition" always going to the declaration?
Refactoring. Yes I know it's formally impossible because of the pre-processor - but the compiler could still do a better job of a search and replace on a variable name than I can maually. You could also syntax highlight local, members and paramaters while your at it.
Lint. So the variable I just defined shadows a higher one? C would have told me that in 1979, but c++ in 2009 apparently prefers me to find out on my own.
Some decent error messages. If I promise never to define a class with the same name inside the method of a class - do you promise to tell me about a missing "}". In fact can the compiler have some knowledge of history - so if I added an unbalanced "{" or "(" to a previously working file could we consider mentioning this in the message?
Can the STL error messages please (sorry to quote another comment) not look like you read "/dev/random", stuck "!/bin/perl" in front and then ran the tax code through the result?
How about some warnings for useful things? "Integer used as bool performance warning" is not useful, it doesn't make any performance difference, I don't have a choice - it's what the library does, and you have already told me 50 times. But if I miss a ";" from the end of a class declaration or a "}" from the end of a method definition you don't warn me - you go out of your way to find the least likely (but theoretically) correct way to parse the result. It's like the built in spell checker in this browser which happily accepts me misspelling wether (because that spelling is an archaic term for a castrated male goat! How many times do I write about soprano herbivores?)
How about spell checking? 40 years ago mainframe Fortran compilers had spell checking so if misspelled "WRITE" you didn't come back the next day to a pile of cards and a snotty error message. You got a warning that "WRIET" had been changed to WRITE in line X. Now the compiler happily continues and spends 10mins building some massive browse file and debugger output before telling you that you misspelled prinft 10,000 lines ago.
A compiler which tries to optimize the compilation model.
Rather than naively include headers as needed, parsing them again in every compilation unit, why not parse the headers once first, build complete syntax trees for them (which would have to include preprocessor directives, since we don't yet know which macros are defined), and then simply run through that syntax tree whenever the header is included, applying the known #defines to prune it.
It could even be be used as a replacement for precompiled headers, so every header could be precompiled individually, just by dumping this syntax tree to the disk. We wouldn't need one single monolithic and error-prone precompiled header, and would get finer granularity on rebuilds, rebuilding as little as possible even if a header is modified.
Like my other suggestions, this would be a lot of work to implement, but I can't see any fundamental problems rendering it impossible.
It seems like it could dramatically speed up compile-times, pretty much rendering it linear in the number of header files, rather than in the number of #includes.
重构,重构,重构。 并在打字时进行编译。 对于重构,我至少缺少大多数现代 Java IDE 功能的一半。 虽然 Visual Assist X 已经取得了长足的进步,但仍缺少大量重构。 编写 C++ 代码的任务仍然差不多。 编写 C++ 代码。 IDE 越支持高级重构,它就越容易构建,结构的可延展性就越高,迭代结构并改进它就越容易。 选择 Intellij 的演示版本并看看您缺少什么。 这些只是我几年前记得的一些事情。
提取接口:获取具有公共接口的视图类,将公共函数移动到接口类中(对于 C++ 这将是一个抽象基类),并将指定的函数派生为抽象
Refactoring, Refactoring, Refactoring. And compilation while typing. For refactorings I am missing at least half of what most modern Java IDEs can do. While Visual Assist X goes a long way, a lot of refactoring is missing. The task of writing C++ code is still pretty much that. Writing C++ code. The more the IDE supports high level refactoring the more it becomes construction, the more mallable the structure is the easier it will be to iterate over the structure and improve it. Pick up a demo version of Intellij and see what you are missing. These are just some that I remember from a couple of years ago.
Extract interface: taken a view classes with a common interface, move the common functions into an interface class (for C++ this would be an abstract base class) and derive the designated functions as abstract
Better extract method: mark a section of code and have the ide write a function that executes that code, constructing the correct parameters and return values
Know the type of each of the symbols that you are working with so that not only command completion can be correct for derived values e.g. symbol->... but also only offer functions that return the type that can be used in the current expression e.g. for
UiButton button = window->...
At the ... only insert functions that actually return a UiButton.
如果使用 int 作为模板参数调用该函数,那么显然,int 的使用必须有效,因此 IDE 可以将其用作“示例类型”在函数内部并据此提供智能感知建议。
JavaScript 刚刚在 VS 中得到了 Intellisense 支持,必须克服很多类似的问题,所以才可以做到。 当然,考虑到 C++ 的复杂程度,这将是一个荒谬的工作量。 但这将是一个很好的功能。
Intelligent Intellisense/Code Completion even for template-heavy code.
When you're inside a function template, of course the compiler can't say anything for sure about the template parameter (at least not without Concepts), but it should be able to make a lot of guesses and estimates. Depending on how the type is used in the function, it should be able to narrow the possible types down, in effect a kind of conservative ad-hoc Concepts. If one line in the function calls .Foo() on a template type, obviously a Foo member method must exist, and Intellisense should suggest it in the rest of the function as well.
It could even look at where the function is invoked from, and use that to determine at least one valid template parameter type, and simply offer Intellisense inside the function based on that.
If the function is called with a int as a template parameter, then obviously, use of int must be valid, and so the IDE could use that as a "sample type" inside the function and offer Intellisense suggestions based on that.
JavaScript just got Intellisense support in VS, which had to overcome a lot of similar problems, so it can be done. Of course, with C++'s level of complexity, it'd be a ridiculous amount of work. But it'd be a nice feature.
发布评论
评论(12)
执行编码标准的通用工具。
采用所有通用标准,并允许您根据您的项目打开/关闭它们。
目前,usullay 只能用一堆 Perl 脚本来替代。
A common tool to enforce coding standards.
Take all the common standards and allow you to turn them on/off as appropriate for your project.
Currently just a bunch of perl scrips usullay has to supstitute.
快速可靠的索引器。 大多数奇特的功能都是在此之后出现的。
A fast and reliable indexer. Most of the fancy features come after this.
如果谈论 MS Visual Studio C++,Visual Assist 是一个非常方便的代码完成工具,一些重构 - 例如重命名所有/选定的引用、查找/转到声明,但我仍然怀念 JBuilder 或 IntelliJ 等 Java IDE 的丰富性。
我仍然怀念的是一种语义差异工具 - 你知道,它不会逐行比较两个文件,而是语句/表达式。 我在网上找到的只是一些废弃的尝试 - 如果你知道,请写在评论中
If talking about MS Visual Studio C++, Visual Assist is a very handy tool for code completition, some refactorings - e.g. rename all/selected references, find/goto declaration, but I still miss the richness of Java IDEs like JBuilder or IntelliJ.
What I still miss, is a semantic diff tool - you know, one which does not compare the two files line-by-line, but statements/expressions. What I've found on the internet are only some abandoned tries - if you know one, please write in comment
C++ 的主要问题是难以解析。 这就是为什么适用于源代码的工具非常少。 (这也是为什么我们会遇到编译器历史上一些最可怕的错误消息。)结果是,除了极少数例外(我只知道 doxygen 和 Visual Assist),这取决于实际的编译器支持帮助我们编写和修改代码所需的一切。 由于编译器传统上是相当简化的命令行工具,因此构建丰富的编辑器支持的基础非常薄弱。
我与 VS 合作已经大约十年了。 同时,它的代码完成几乎可用。 (是的,我正在双核机器上工作。否则我不会这么说,不是吗?)如果您使用 Visual Assist,代码完成实际上非常好。 如今,VS 本身和 VA 都进行了一些基本的重构。 这也几乎可以用于它的目标(尽管它仍然明显不如代码完成)。 当然,超过 15 年的搜索和重构经验 作为盒子里唯一的工具,与其他语言相比,我的要求可能太糟糕了,所以这可能没有多大意义。
然而,我真正缺乏的仍然是:在我的代码移植到的所有平台上完全符合标准的编译器和标准库实现。而且我说的是在上一个版本发布10年后标准,距离下一个发布大约一年! (这只是添加了这一点:C++1x 在 2011 年被广泛采用。)
一旦这些问题得到解决,就会时不时地提到一些事情,但是哪些供应商仍在努力遵守一个超过 10 年的标准(或者,就像某些功能的实际情况一样,甚至放弃了它),从未抽出时间来实际解决:
operator<<()
通过调用运行时解析给我们带来的所有编译时优势code>printf()
在幕后(Dietmar Kühl 曾经着手这样做,不幸的是他的实现在技术没有得到普及的情况下就夭折了)lint
这样的工具变得无用(不用担心,lint
供应商,这只是一厢情愿的想法)如果所有这些以及我忘记提及的许多其他问题(随意添加)都得到解决,那就太好了重构支持几乎与 Java 或 C# 处于同一联盟。 但只有那时。
The main problem with C++ is that it is hard to parse. That's why there are so very few tools out there that work on source code. (And that's also why we're stuck with some of the most horrific error messages in the history of compilers.) The result is, that, with very few exceptions (I only know doxygen and Visual Assist), it's down to the actual compiler to support everything needed to assist us writing and massaging the code. With compilers traditionally being rather streamlined command line tools, that's a very weak foundation to build rich editor support on.
For about ten years now, I'm working with VS. meanwhile, its code completion is almost usable. (Yes, I'm working on dual core machines. I wouldn't have said this otherwise, wouldn't I?) If you use Visual Assist, code completion is actually quite good. Both VS itself and VA come with some basic refactoring nowadays. That, too, is almost usable for the few things it aims for (even though it's still notably less so than code completion). Of course, >15 years of refactoring with search & replace being the only tool in the box, my demands are probably much too deteriorated compared to other languages, so this might not mean much.
However, what I am really lacking is still: Fully standard conforming compilers and standard library implementations on all platforms my code is ported to. And I'm saying this >10 years after the release of the last standard and about a year before the release of the next one! (Which just adds this: C++1x being widely adopted by 2011.)
Once these are solved, there's a few things that keep being mentioned now and then, but which vendors, still fighting with compliance to a >10 year old standard (or, as is actually the case with some features, having even given up on it), never got around to actually tackle:
operator<<()
gives us by resorting to calling the run-time-parsingprintf()
under the hood (Dietmar Kühl once set out to do this, unfortunately his implementation died without the techniques becoming widespread)lint
useless (no need to fear,lint
vendors, that's just wishful thinking)If all these and a lot of others that I have forgotten to mention (feel free to add) are solved, it would be nice to get refactoring support that almost plays in the same league as, say, Java or C#. But only then.
我梦想的工具是编译时模板调试器。 它可以让我以交互方式逐步执行模板实例化,并在实例化类型时检查类型,就像常规调试器在运行时所做的那样。
My dream tool would be a compile-time template debugger. Something that'd let me interactively step through template instantiations and examine the types as they get instantiated, just like the regular debugger does at runtime.
代码完成。 严重地。 重构是一个很好的功能,但我认为代码完成对于 API 的可发现性和可用性来说更为基础和重要。
基本上,需要理解 C++ 代码的工具很糟糕。
Code completion. Seriously. Refactoring is a nice-to-have feature but I think code completion is much more fundamental and more important for API discoverabilty and usabilty.
Basically, tools that require any undestanding of C++ code suck.
类方法的代码生成。 当我输入声明时,您应该能够找出定义。 当我谈论这个主题时,我们可以修复“转到声明/转到定义”总是转到声明吗?
重构。 是的,我知道由于预处理器的原因,这在形式上是不可能的 - 但编译器仍然可以比我手动更好地搜索和替换变量名。 您还可以在使用时语法突出显示本地、成员和参数。
皮棉。 那么我刚刚定义的变量隐藏了一个更高的变量? 在 1979 年,C 会告诉我这一点,但 2009 年的 C++ 显然更喜欢我自己去发现。
一些不错的错误消息。 如果我保证永远不会在类的方法中定义具有相同名称的类 - 您是否答应告诉我缺少“}”的情况。 事实上,编译器可以有一些历史知识 - 所以如果我在以前的工作文件中添加了不平衡的“{”或“(”,我们可以考虑在消息中提及这一点吗?
STL错误消息可以吗(抱歉引用另一条评论)看起来不像你读了“/dev/random”,把“!/bin/perl”放在前面,然后通过结果运行税务代码?
“整数用作布尔性能警告”怎么样?没用,它不会产生任何性能差异,我别无选择 - 这就是图书馆所做的,你已经告诉我 50 次了。
但如果我错过了一个“;” 从类声明的末尾或从方法定义的末尾开始的“}”,您不会警告我 - 您会竭尽全力寻找最不可能(但理论上)正确的方法来解析结果。
就像这个浏览器中内置的拼写检查器一样,它很乐意接受我的拼写错误(因为该拼写是阉割公山羊的古老术语!我写了多少次关于女高音食草动物的文章?)
拼写检查怎么样? 40 年前,大型机 Fortran 编译器具有拼写检查功能,因此,如果拼写错误“WRITE”,您第二天不会看到一堆卡片和一条令人讨厌的错误消息。 您收到一条警告,指出 X 行中的“WRIET”已更改为 WRITE。现在,编译器愉快地继续并花费 10 分钟构建一些大量的浏览文件和调试器输出,然后告诉您 10,000 行前拼错了 prinft。
附: 是的,其中很多仅适用于 Visual C++。
pps。 是的,他们现在带着我的药物来了。
Code generation of class methods. When I type in the declaration you should be able to figure out the definition. And while I'm on the topic can we fix "goto declaration / goto definition" always going to the declaration?
Refactoring. Yes I know it's formally impossible because of the pre-processor - but the compiler could still do a better job of a search and replace on a variable name than I can maually. You could also syntax highlight local, members and paramaters while your at it.
Lint. So the variable I just defined shadows a higher one? C would have told me that in 1979, but c++ in 2009 apparently prefers me to find out on my own.
Some decent error messages. If I promise never to define a class with the same name inside the method of a class - do you promise to tell me about a missing "}". In fact can the compiler have some knowledge of history - so if I added an unbalanced "{" or "(" to a previously working file could we consider mentioning this in the message?
Can the STL error messages please (sorry to quote another comment) not look like you read "/dev/random", stuck "!/bin/perl" in front and then ran the tax code through the result?
How about some warnings for useful things? "Integer used as bool performance warning" is not useful, it doesn't make any performance difference, I don't have a choice - it's what the library does, and you have already told me 50 times.
But if I miss a ";" from the end of a class declaration or a "}" from the end of a method definition you don't warn me - you go out of your way to find the least likely (but theoretically) correct way to parse the result.
It's like the built in spell checker in this browser which happily accepts me misspelling wether (because that spelling is an archaic term for a castrated male goat! How many times do I write about soprano herbivores?)
How about spell checking? 40 years ago mainframe Fortran compilers had spell checking so if misspelled "WRITE" you didn't come back the next day to a pile of cards and a snotty error message. You got a warning that "WRIET" had been changed to WRITE in line X. Now the compiler happily continues and spends 10mins building some massive browse file and debugger output before telling you that you misspelled prinft 10,000 lines ago.
ps. Yes a lot of these only apply to Visual C++.
pps. Yes they are coming with my medication now.
尝试优化编译模型的编译器。
与其天真地根据需要包含标头,在每个编译单元中再次解析它们,为什么不首先解析标头一次,为它们构建完整的语法树(这必须包含预处理器指令,因为我们还不知道定义了哪些宏),然后只要包含标头就简单地运行该语法树,应用已知的 #defines 来修剪它。
它甚至可以用作预编译头的替代品,因此每个头都可以单独预编译,只需将此语法树转储到磁盘即可。 我们不需要一个单一的、容易出错的预编译头,并且在重建时会获得更细的粒度,即使头被修改,重建也尽可能少。
与我的其他建议一样,实施起来需要大量工作,但我看不出有任何根本问题使其不可能。
看起来它可以极大地加快编译时间,几乎使其与头文件的数量呈线性关系,而不是与 #include 的数量呈线性关系。
A compiler which tries to optimize the compilation model.
Rather than naively include headers as needed, parsing them again in every compilation unit, why not parse the headers once first, build complete syntax trees for them (which would have to include preprocessor directives, since we don't yet know which macros are defined), and then simply run through that syntax tree whenever the header is included, applying the known #defines to prune it.
It could even be be used as a replacement for precompiled headers, so every header could be precompiled individually, just by dumping this syntax tree to the disk. We wouldn't need one single monolithic and error-prone precompiled header, and would get finer granularity on rebuilds, rebuilding as little as possible even if a header is modified.
Like my other suggestions, this would be a lot of work to implement, but I can't see any fundamental problems rendering it impossible.
It seems like it could dramatically speed up compile-times, pretty much rendering it linear in the number of header files, rather than in the number of #includes.
重构,重构,重构。 并在打字时进行编译。 对于重构,我至少缺少大多数现代 Java IDE 功能的一半。 虽然 Visual Assist X 已经取得了长足的进步,但仍缺少大量重构。 编写 C++ 代码的任务仍然差不多。 编写 C++ 代码。 IDE 越支持高级重构,它就越容易构建,结构的可延展性就越高,迭代结构并改进它就越容易。 选择 Intellij 的演示版本并看看您缺少什么。 这些只是我几年前记得的一些事情。
提取接口:获取具有公共接口的视图类,将公共函数移动到接口类中(对于 C++ 这将是一个抽象基类),并将指定的函数派生为抽象
更好的提取方法:标记一段代码并让 ide 编写一个执行该代码的函数,构造正确的参数和返回值
知道您正在使用的每个符号的类型,以便不仅命令完成对于派生值来说是正确的,例如符号->...,而且还只提供返回可在当前表达式中使用的类型的函数,例如对于
UiButton 按钮 = window->...
在 ... 处仅插入实际返回 UiButton 的函数。
Refactoring, Refactoring, Refactoring. And compilation while typing. For refactorings I am missing at least half of what most modern Java IDEs can do. While Visual Assist X goes a long way, a lot of refactoring is missing. The task of writing C++ code is still pretty much that. Writing C++ code. The more the IDE supports high level refactoring the more it becomes construction, the more mallable the structure is the easier it will be to iterate over the structure and improve it. Pick up a demo version of Intellij and see what you are missing. These are just some that I remember from a couple of years ago.
Extract interface: taken a view classes with a common interface, move the common functions into an interface class (for C++ this would be an abstract base class) and derive the designated functions as abstract
Better extract method: mark a section of code and have the ide write a function that executes that code, constructing the correct parameters and return values
Know the type of each of the symbols that you are working with so that not only command completion can be correct for derived values e.g. symbol->... but also only offer functions that return the type that can be used in the current expression e.g. for
UiButton button = window->...
At the ... only insert functions that actually return a UiButton.
我对 C++ 工具的现状非常满意。 我唯一能想到的是在 VS/gcc 中默认安装 Boost。
I'm pretty happy with the state of C++ tools. The only thing I can think of is a default install of Boost in VS/gcc.
一个完全独立的工具:命名约定。
A tool all on it's own: Naming Conventions.
智能智能感知/代码完成,即使对于模板较多的代码也是如此。
当你在函数模板中时,编译器当然不能肯定说出关于模板参数的任何信息(至少不能没有概念),但它应该能够做出很多猜测和估计。 根据类型在函数中的使用方式,它应该能够缩小可能的类型范围,实际上是一种保守的临时概念。 如果函数中的一行在模板类型上调用 .Foo(),显然必须存在 Foo 成员方法,并且 Intellisense 也应该在函数的其余部分中建议它。
它甚至可以查看函数的调用位置,并使用它来确定至少一种有效的模板参数类型,并根据该类型在函数内部提供 Intellisense。
如果使用
int
作为模板参数调用该函数,那么显然,int
的使用必须有效,因此 IDE 可以将其用作“示例类型”在函数内部并据此提供智能感知建议。JavaScript 刚刚在 VS 中得到了 Intellisense 支持,必须克服很多类似的问题,所以才可以做到。 当然,考虑到 C++ 的复杂程度,这将是一个荒谬的工作量。 但这将是一个很好的功能。
Intelligent Intellisense/Code Completion even for template-heavy code.
When you're inside a function template, of course the compiler can't say anything for sure about the template parameter (at least not without Concepts), but it should be able to make a lot of guesses and estimates. Depending on how the type is used in the function, it should be able to narrow the possible types down, in effect a kind of conservative ad-hoc Concepts. If one line in the function calls .Foo() on a template type, obviously a Foo member method must exist, and Intellisense should suggest it in the rest of the function as well.
It could even look at where the function is invoked from, and use that to determine at least one valid template parameter type, and simply offer Intellisense inside the function based on that.
If the function is called with a
int
as a template parameter, then obviously, use ofint
must be valid, and so the IDE could use that as a "sample type" inside the function and offer Intellisense suggestions based on that.JavaScript just got Intellisense support in VS, which had to overcome a lot of similar problems, so it can be done. Of course, with C++'s level of complexity, it'd be a ridiculous amount of work. But it'd be a nice feature.