Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "CDT/Obsolete/C editor enhancements/Include management"

(Page rewrite and cleanup, added some details)
(Missed to keep some lines from the previous version; added them now again.)
Line 1: Line 1:
''This is a problem page. Please treat it as a discussion page and feel free to insert your comments.''
+
''This is a problem page. Please treat it as a discussion page and feel free to insert your comments anywhere. My open questions are in bold''--[[User:Kosashi.gmail.com|Tomasz Wesołowski]] 14:22, 30 April 2010 (UTC)
  
 
==Problem==
 
==Problem==
Line 18: Line 18:
 
** Remove all unused/Flattern (include directly used)
 
** Remove all unused/Flattern (include directly used)
 
* Editor
 
* Editor
** Folding  
+
** Folding
 +
 
 +
===Ranking===
 +
 
 +
4/5 [[User:Eclipse.sprigogin.gmail.com|Sergey Prigogin]] 07:16, 18 May 2010 (UTC)
 +
 
 +
4/5 [[User:Tobias.hahn.ableton.com|Tobias Hahn]] 09:32, 18 May 2010 (UTC)
 +
 
 +
4/5 [[User:Jens.elmenthaler.verigy.com|Jens Elmenthaler]]
 +
 
 +
4/5 [[Kirstin Weber]]
  
 
===Inspiration===
 
===Inspiration===
Line 28: Line 38:
 
===Solution proposal===
 
===Solution proposal===
  
A possible solution is to make CDT work like JDT. The problem gets a bit more complex in C/C++, though. [https://bugs.eclipse.org/bugs/show_bug.cgi?id=45203 Bug 45203] is about this proposed "Organize includes" feature.
+
A possible solution is to make CDT work like JDT. The problem gets a bit more complex in C/C++, though.
  
 
==Invocation==
 
==Invocation==
Line 36: Line 46:
 
A JDT-like solution would be to integrate adding includes with Context Assist.
 
A JDT-like solution would be to integrate adding includes with Context Assist.
  
Implementing a JDT-like solution would require little change to Context Assist behaviour. Context Assist, when invoked from a context with a part of name entered, would need to display a set of indexed symbols; ideally sorted in some clever way. A selection of not-yet-included option would invoke the include directive generation.
+
Implementing a JDT-like solution would require little change to Context Assist behaviour. Context Assist, when invoked from a context with a part of name entered, would need to display a set of indexed symbols; ideally sorted in some clever way - '''how exactly?'''. A selection of not-yet-included option would invoke the include directive generation.
 
+
Also see [https://bugs.eclipse.org/bugs/show_bug.cgi?id=291977 bug 291977].
+
  
 
===Annotations===
 
===Annotations===
Line 103: Line 111:
 
In contrast to Java, reordering inclusions can change the compilation unit in C/C++. Conditional compilations, comments, includes mixed within code etc. can complicate things. Another sort "order" could therefore be to aim to keep the original order of include directives as far as possible.
 
In contrast to Java, reordering inclusions can change the compilation unit in C/C++. Conditional compilations, comments, includes mixed within code etc. can complicate things. Another sort "order" could therefore be to aim to keep the original order of include directives as far as possible.
  
==Removal of unused includes ==
+
==Marking / removing unused includes ==
  
 
Marking of unused includes could be implemented as a Codan checker.
 
Marking of unused includes could be implemented as a Codan checker.
Line 131: Line 139:
 
A little handy detail related to this problem would be to provide a possibility to fold a block of include directives and / or a block of forward declarations.
 
A little handy detail related to this problem would be to provide a possibility to fold a block of include directives and / or a block of forward declarations.
  
==Ranking==
+
==References==
  
4/5 [[User:Eclipse.sprigogin.gmail.com|Sergey Prigogin]] 07:16, 18 May 2010 (UTC)
+
The proposed "Organize Includes" feature: [https://bugs.eclipse.org/bugs/show_bug.cgi?id=45203 Bug 45203]
  
4/5 [[User:Tobias.hahn.ableton.com|Tobias Hahn]] 09:32, 18 May 2010 (UTC)
+
Adding includes with Context Assist: [https://bugs.eclipse.org/bugs/show_bug.cgi?id=291977 Bug 291977]
 
+
4/5 [[User:Jens.elmenthaler.verigy.com|Jens Elmenthaler]]
+
 
+
4/5 [[Kirstin Weber]]
+
 
+
==References==
+
  
Bug reports about the proposed "Organize Includes" feature: [https://bugs.eclipse.org/bugs/show_bug.cgi?id=45203 Bug 45203] and [https://bugs.eclipse.org/bugs/show_bug.cgi?id=291977 Bug 291977]
+
Problem with the "Add Include" feature (already fixed): [https://bugs.eclipse.org/bugs/show_bug.cgi?id=182897 Bug 182897]
  
Problems with the already existing "Add Include" feature: [https://bugs.eclipse.org/bugs/show_bug.cgi?id=182897 Bug 182897] (already fixed), [https://bugs.eclipse.org/bugs/show_bug.cgi?id=113063 Bug 113063] (apparently also already fixed?)
+
Problem with the "Add Include" feature (apparently also already fixed?): [https://bugs.eclipse.org/bugs/show_bug.cgi?id=113063 Bug 113063]

Revision as of 05:22, 29 April 2012

This is a problem page. Please treat it as a discussion page and feel free to insert your comments anywhere. My open questions are in bold--Tomasz Wesołowski 14:22, 30 April 2010 (UTC)

Problem

Description

The management of include directives is probably one of the most repetitive tasks in C/C++ programming.

There's already an "Add include" feature, but it has its drawbacks: needs manual invocation by the programmer and is inaccurate in numerous situations. Clearly there's a lot of space for improvement.

Possible tools includes:

  • Checkers/Quick fixes
    • Find unused includes
    • Find indirect includes used (i.e. we use a.h but we don't include it but we include b.h which includes a.h)
    • Find all files that needs to be included
  • Refactoring
    • Sort includes
    • Remove all unused/Flattern (include directly used)
  • Editor
    • Folding

Ranking

4/5 Sergey Prigogin 07:16, 18 May 2010 (UTC)

4/5 Tobias Hahn 09:32, 18 May 2010 (UTC)

4/5 Jens Elmenthaler

4/5 Kirstin Weber

Inspiration

JDT features wonderful include handling. If the Java include path is set correctly, then the programmer probably never has to add an import manually and is thus not distracted from actual coding.

The addition of new import can be done in two ways: when selecting a class from Context Assist which is not yet imported, or by invoking Organize Includes. JDT also warns about and allows to remove unused imports.

Solution proposal

A possible solution is to make CDT work like JDT. The problem gets a bit more complex in C/C++, though.

Invocation

Context Assist

A JDT-like solution would be to integrate adding includes with Context Assist.

Implementing a JDT-like solution would require little change to Context Assist behaviour. Context Assist, when invoked from a context with a part of name entered, would need to display a set of indexed symbols; ideally sorted in some clever way - how exactly?. A selection of not-yet-included option would invoke the include directive generation.

Annotations

The not-yet-included elements can be annotated with the defining header file in-place, so that users can easily invoke the include directive generation.

Menus

Organizing the include directives should also be possible via the main and context menus.

Generation

The generation of an include directive is also not a trivial task, as it is in Java. Include directives can be generated in different ways. It probably makes sense to introduce some user preference options which control the mode of inclusion.

Quotes vs. angle brackets

Include directives can either use quotes or angle brackets to specify the header which should be included. It's common to use the quoted form to include user-defined headers, and the angle bracket form to include (standard) library headers.

Since it can be problematic to determine whether a given header file is "user-defined" or not, there should be a way to let the user specify for a given include directory whether the header files contained therein should be included by quotes or angle brackets.

However, header files which are contained within the same project as the source file can probably always be included by using the quoted form, since they usually have been created by the user himself.

Path to use

Include directives which use the quoted form can always use a relative path to specify the target header (e.g. "header.h", "dir/header.h" or "../header.h"). Depending on the include paths, it may however be possible to include the same header in different ways. For example, it might be possible to include the same header via "header.h" and "path/to/header/header.h" if "path/to/header" is on the include path.

It probably makes sense to use the shortest path by default - i.e. to prefer to include "header.h" instead of "path/to/header/header.h". It however should be possible to fine-tune this behavior via preference options, for example as follows:

Prefer to include headers relative to the source file if located in...

  • ...the same directory as the source file (enabled by default)
  • ...a subdirectory of the source file's directory (enabled by default)
  • ...a parent directory of the source file's directory (disabled by default)

Headers which use angle brackets are usually relative to only one specific (system) include path, and aren't included relative to any source files. The problem of different include paths therefore doesn't apply to them.

Forward declarations

We often only need a simple forward declaration instead of a full definition. The feature should decide which one is required so that compilation times can be reduced. There should be user preference options about the usage of forward declarations for classes, structs, unions and enums. This should probably be enabled by default except for enums since usage of enum forward declarations require the new C++11 standard.

Check this document about a summary of when forward declarations can be used and when not.

No direct inclusion of specific headers

Some header files are not intended for direct inclusion. For example, std::set is defined in bits/stl_set.h, which contains a comment:

"This is an internal header file, included by other library headers. You should not attempt to use it directly.". It is a well known fact that in order to use std::set somebody has to include <set>, not <bits/stl_set.h>. Unfortunately, CDT currently doesn't know about this rule.

Sort order

Include directives can be sorted in various ways. It therefore would make sense to introduce some user preference options to control the sort order. Possible sort orders are:

By header file location

Include directives can be sorted by the location of the included header file. For example, the sort order might be as follows:

Library headers > Project-relative headers > File-relative headers > Forward declarations

Alphabetically

Include directives can be sorted alphabetically.

Original order

In contrast to Java, reordering inclusions can change the compilation unit in C/C++. Conditional compilations, comments, includes mixed within code etc. can complicate things. Another sort "order" could therefore be to aim to keep the original order of include directives as far as possible.

Marking / removing unused includes

Marking of unused includes could be implemented as a Codan checker.

This task may be more tricky to implement than in Java. To decide if a header is used, we'd also need to check symbols in a compilation unit against all headers included by it, recursively. Browsing a big hierarchy of headers against occurrences of a given symbol might be time-consuming on bigger projects.

Java has "flat" imports, so this problem doesn't exist there.

Do you believe that such feature is neccessary?

  • [Markus Schorn]: In general you will not be able to determine whether a header file needs to be included. Here are a few different examples for that:
    • Including a file that contains inline function definitions: The compiler does not need the definitions, the linker will complain.
    • Including a file that contains #undef statements: You will not find references for the undefined macro, however removing the statement may change the way your code is compiled.
      • It can be detected too - i.e. if it is not used by any header below it and compilation unit - it won't affect it (Elaskavaia.cdt.gmail.com 18:49, 17 May 2010 (UTC))
    • Similar for #pragma statements that affect the way code is compiled.
    • Headers that are necessary dependent on compiler switches.
      • You mean header that are included (or not) using conditional compilation? (Elaskavaia.cdt.gmail.com 18:49, 17 May 2010 (UTC))
  • Elaskavaia.cdt.gmail.com 18:49, 17 May 2010 (UTC)
    • Yes it is not error prone however I think checker like that would be very useful. User should judge if he wants to remove header or not manually. I have done such checker before it can easily take a month on its own (plus other include checkers).
  • [Kirstin Weber]: I think support for includes is very helpful. It is one of the great features for Java and I really miss it when I write C++ code again. In Java unnecessary imports are marked immediately. If this is too time-consuming or hard/impossible to find out for C++ immediately it would be helpful if there would be a "clean up" function, perhaps after compiling. You compile the code and afterwards you invoke such a feature and all unnecessary imports are removed. You can use such a feature when you have finished your implementation in order to clean up your code at the end.

Folding

A little handy detail related to this problem would be to provide a possibility to fold a block of include directives and / or a block of forward declarations.

References

The proposed "Organize Includes" feature: Bug 45203

Adding includes with Context Assist: Bug 291977

Problem with the "Add Include" feature (already fixed): Bug 182897

Problem with the "Add Include" feature (apparently also already fixed?): Bug 113063

Back to the top