July 11th, 2023

#include cleanup in Visual Studio

Mryam Girmay
Program Manager

We are gradually rolling out this feature in Visual Studio 2022 version 17.8 to monitor some data. This means that not everyone will have access to the feature immediately after its release.

We are thrilled to announce the return of #include cleanup, a tool that helps you maintain clean code, now available in Visual Studio 17.8 Preview 1. To start using this feature, make sure to update to the latest version of Visual Studio Preview.

#include cleanup 

Visual Studio now offers #include cleanup, a feature that improves the quality of your code by generating suggestions to remove unused headers and add direct headers. Our suggested workflow is to first go through the direct include suggestions to add direct headers where indirect headers are used, followed by removing the unused includes.

Remove unused #include statements 

This feature provides suggestions to remove unused headers from your files, enhancing code cleanliness. When an unused include is detected, it is visually dimmed by default. By hovering over the dimmed include, a quick action (indicated by three dots in the default view) prompt will appear, notifying you about the unused include in the file. You can click on the light bulb to remove the unused include or all unused includes. This makes it easier to clean up your code and ensures that you keep only the necessary includes to keep your code well-organized.

Gif showing remove unused includes.
Gif showing remove unused includes.

Add transitively used #include statements 

In Visual Studio, there is an existing feature that alerts users when an include is used but not added to the file. This is indicated by a squiggle and suggests adding the required include. Currently, we have added a new feature that provides suggestions for adding direct includes when your file has indirect dependencies. Including indirect dependencies can result in longer compilation times. However, with the help of direct include suggestions, you can optimize compilation time by including only the essential direct dependencies.

In instances where the direct include for certain content is missing, a quick action (indicated by three dots in the default view) will appear. Hovering over it will inform you that content from that transitive include is being used. Then, you have the option to either add the direct include individually or add all transitively used includes. By choosing to include all transitively used includes, all the direct headers will be automatically added wherever indirect headers are used in the file. After including the direct dependencies, it is crucial to remove any unused includes, retaining only those that are necessary.

Gif showing add direct include suggestion.
Gif showing add direct include suggestion.

To quickly perform code cleanup, you can configure code cleanup by adding “Add transitively used and remove unused #include statements (C++)”. Once this setup is complete, you’ll have the convenience of adding all transitively used includes and removing all unused includes with just a single click on the broom icon. This streamlines the process and ensures that your code remains clean.

Gif displaying Configure Code Cleanup
Gif displaying Configure Code Cleanup.

By default, #include cleanup is disabled, but you can enable it by navigating to Tools > Options > Text Editor > C/C++ > IntelliSense and selecting “Enable #include cleanup.” Once enabled, you have the flexibility to adjust the settings and configure different levels to meet your specific needs and preferences.

Image displaying Code cleanup setting.
Image displaying code cleanup setting.

Customization Options

You have the flexibility to customize how the #include cleanup generates suggestions, allowing it to seamlessly adapt and integrate with intricate and extensive codebases. By making these changes or adjustments, you can ensure that the process better aligns with the specific needs and complexities of your project, resulting in a more efficient and effective code cleanup. In the EditorConfig (EditorConfig settings), you can add a single header, and if you want to include multiple headers, you should separate them using commas.

Exclude Files 

To exclude specific includes from #include cleanup suggestions, you can utilize EditorConfig. This allows you to categorize and define which files should not be considered for suggestions, providing greater control over the suggestions generated by #include cleanup. Examples of excluding single and multiple files (exclude vcruntime.h and vcruntime_string.h from cleanup suggestions):

cpp_include_cleanup_excluded_files = vcruntime.h
cpp_include_cleanup_excluded_files = vcruntime.h,vcruntime_string.h
Required Files

In cases where headers require other headers, and you don’t want suggestions generated, you can specify the dependencies in the EditorConfig. This ensures that required files won’t be marked as unused. Examples of single and multiple required files (atlwin.h requires altbase.h and atlcom.h requires altbase.h):

cpp_include_cleanup_required_files = atlwin.h:altbase.h
cpp_include_cleanup_required_files = atlwin.h:altbase.h,atlcom.h:altbase.h
Files Replacement

This feature also supports the remapping of facade headers. If a file is intended to represent a different file, you can redirect the usage of the first file to the usage of the second file in EditorConfig. Examples of single and multiple replaced files (replace stdio.h by cstdio, and replace stdint.h by cstdint):

cpp_include_cleanup_replacement_files = stdio.h:cstdio
cpp_include_cleanup_replacement_files = stdio.h:cstdio,stdint.h:cstdint
Alternate Files 

In certain situations, you may have alternative options for including a file, such as facade files. When the usage of one file can be considered as an alternative to the usage of another file, you can specify this relationship in EditorConfig. By doing so, you can prevent #include cleanup from generating suggestions for alternate matches. Examples of single and multiple alternate files (windows.h is an alternate for minwindef.h and windows.h is an alternate for winerror.h):

cpp_include_cleanup_alternate_files = windows.h:minwindef.h
cpp_include_cleanup_alternate_files = windows.h:minwindef.h,windows.h:winerror.h

Send us your feedback! 

Explore #Include Cleanup by downloading the latest version of Visual Studio Preview. We genuinely value your feedback as it plays a crucial role in shaping our development process. Please share your thoughts in the comments below, on Developer Community, or reach out to us on Twitter (@VisualC) or via email at visualcpp@microsoft.com. Your input is highly appreciated! 

 

Author

Mryam Girmay
Program Manager

29 comments

Discussion is closed. Login to edit/delete existing comments.

  • Hojjat Jafary · Edited

    It suggests removing some required header files in Unreal Engine game projects, such as

    *.generated.h

    files, and seems excluding them with wildcarding is not working too.

    • Keith StockdaleMicrosoft employee · Edited

      I can confirm that I am seeing this as well. I have tried the following:

      <code>

      and

      <code>

      Neither of these work. It would be cool if adding a wildcard to the option could be added. Or if there is a way of doing this already, it would be great if the blog could be updated to mention how to do it.

      Read more
      • Raul PerezMicrosoft employee

        Thanks for taking the time to provide the feedback. For 17.8 we’ve added support to implicitly support UE generated files in the tool.

        For the suggestion of supporting wildcards. Currently that’s not supported however if you’d like to see that please head over to developer community and open a suggestion ticket there so that we can prioritize the request.

  • duckdoom5 · Edited

    Our code style forces the use of

    #include "header.h"

    instead of

    #include <header.h>

    Is there a way to force this code style?

    I did some googling, but couldn’t find anything.

    • Raul PerezMicrosoft employee

      Thanks for the feedback, we are going to have that available as a general setting for all features that suggest includes however it’s not available just yet. The setting will allow overriding the default recommendation, which goes through some heuristics to determine quotes or angle brackets, with either quotes or angle brackets.

  • Alexander Y. · Edited

    Do you have manual for the VS2022 "code cleanup" for the C++? This one code-styles-and-code-cleanup is for C#.

    What fixers from the list work on C++ ? Where I can find descriptions of the C++ fixers?
    Code cleanup work for each file, but do nothing in the right click on the project or the solution.

    Also "format document (C++)" converts indentation spaces to tabs, what I was not expecting: I have more-or-less default settings (replace tab to...

    Read more
    • Raul PerezMicrosoft employee

      We don't have documentation on the code cleanup part yet however to quickly answer your question - All of the ones that are suffixed with (C++) are the ones that are C++ specific. Currently as you noticed it's only implemented on a per open document basis as it requires some info that currently is only calculated for open files. If you're interested on the per solution one please head over to developer community and open...

      Read more
  • A A

    Great feature and a great article, but do the images in this blog post really have to be 5 MB in size (total)? Could have used JPEG with no problems, and saved my mobile Internet traffic.

  • Tony Riviere

    It would be nice to have an option to use either “” or for includes based on custom rules.
    Typically, in my code base I use “” for my own includes and for third-party includes (including the std, Qt, and other headers which have a certain pattern in their location path). This allows me to set up different level of warnings for “external headers” which are identified by .

    • Raul PerezMicrosoft employee

      Hi Tony,

      Thanks for the feedback. Could you please open a suggestion ticket with that request in Developer Community? We’re certainly interested in what other kind of customizations would be useful aside from the ones already included.

  • Krzysztof Kawa · Edited

    Would it be possible to add some way for a library to specify the replacement and alternate files? Let's say my project uses stl, boost and Qt, which are all enormous in size and number of files/classes. I can't imagine specifying hundreds (if not thousands) of rules manually separately for every project.

    Also would it be possible that the Microsoft provided libraries (like stl, atl or winapi headers for example) had those rules applied by default?...

    Read more
    • Raul PerezMicrosoft employee

      Hi Krysztof,

      Thanks for the feedback. Having a way for libraries themselves to specify settings is something on our roadmap but I don’t have any more immediate news on that. We are however adding some of the bigger more populate libraries to the default lists. In order to help us prioritize please open a suggestion for libraries that are important to you on Developer Community which other folks can upvote.

  • Joan Marce i Igual

    Will this support Include What You Use directives?
    Like how you can make a header that exports other headers and so.

    • Raul PerezMicrosoft employee

      Hi Joan,

      I'll reiterate Mryam's note about sharing your suggestions in Developer Community. If you haven't had a chance to do so yet we were looking at this and two of us had two different interpretations of your comment so wanted to ask a clarifying question. Are you asking about in source suppressions, in source suppressions using the exact same syntax as Include What You Use or just having the ability to customize the tool? If...

      Read more
    • Mryam GirmayMicrosoft employee Author

      Hi Joan.
      Thank you for your feedback! Currently, the feature does not support Include What You Use directives. We are continuously working on improving the tool, and your input is valuable to us. Feel free to share your suggestions in Developer Community

  • Tom Kirby-Green

    Love this. Transitive and redundant includes are a massive bother and goodness knows, for most of us, it’s going to be a long, long time until C++ Modules becomes part of our day to day experience, so I really appreciate the investment here when it comes to improving the existing (and massively dominant) infrastructure. Kudos to all involved <3.

  • Luc Nanquette · Edited

    Really nice to see this being implemented.
    But it’s still a bit buggy. SFML includes are marked as not needed, even though they are used in all my files 😉

    Edit:
    Ok, so it seems that only the overhead includes like SFML/Graphics.hpp or SFML/Window.hpp are not recognized.
    It wants me to include all headers one by one like SFML/Graphics/RenderTarget.hpp or SFML/Window/Window.hpp, and so on ….

    • Raul PerezMicrosoft employee

      Hi Luc,

      Thanks for trying the feature out and the feedback. If I'm understanding correctly SML/Window.hpp is using a facade pattern. If your preference is to use the facade vs the individual files you can add an editorconfig file and add this setting where you'd replace the entries for the ones in your facade header:

      <code>

      Read more
  • Mason Boswell

    Can this be used with just the command line tools?

    • Wim L

      I’m also interested in a command line tool option.
      So it can be automated in CI, or at least give a warning.

      • Mryam GirmayMicrosoft employee Author · Edited

        Hello,
        No, it doesn’t currently support the use of command line tools. However, we appreciate you raising the question and showing interest in different usage scenarios. I have created Command line tool option for #include cleanup, please upvote it.

    • anonymous

      this comment has been deleted.