VS Code C++ Extension 1.25 Release: Explain C++ symbols using Copilot & Customize recursive include paths

The 1.25 release of the C++ extension in Visual Studio Code introduces a new way to understand your code faster with GitHub Copilot-powered symbol summaries, as well as new customization options for recursive #include path processing. With these enhancements, you gain AI-powered insights into unfamiliar or undocumented code and can optimize IntelliSense performance based on your preferences. 

 Experience these new features for yourself by updating to version 1.25 

Copilot Hover

Want to understand your unfamiliar codebases like undocumented library code quicker without having to navigate around files and read several lines of code? Looking for easy-to-digest information in the middle of your coding task to help get you started? 

GitHub Copilot now leverages C++ language services to provide summaries of symbols that you would like to learn more about or are lacking documentation. This requires an active GitHub Copilot subscription, now available to try for free. 

When you hover over any symbol, you’ll now have an option to Generate Copilot summary. 

Image of a cursor on the variable ctx_server which then shows a popup that have the word generate copilot summary.

Copilot will leverage context provided by C++ language services to generate more information on a given symbol for you no matter where you are in your codebase, using its declaration or definition information. For example, see how it helps understand the ctx_server struct from llama.cpp, an LLM inference written in C/C++. 

Gif showing that you can hover over a variable, click on the popup that then appears. This when shows you a summary of the code that you have written.

Please let us know any feedback on the user experience by commenting on our open issue tracking this. 

Customize Recursive #include Processing  

Have you ever worked on a project that wasn’t configured and had issues with recursive #includes? With this release, we have introduced three new settings to give you more control over how recursive include paths are processed. This lets you tune IntelliSense for better correctness and performance in your project.  

The ideal way to configure the C++ Extension is with a configuration provider (such as CMake Tools) or a compile_commands.json file, which will provide the configuration for IntelliSense. Otherwise, the C++ extension, by default, adds a ‘recursive’ include path to your configuration which searches all subdirectories of your workspace as if they were #include paths. Recursion is indicated by appending /** to your include path in your c_cpp_properties.json file: 

Screenshot of the c_cpp_properties.json file showing the includepath being set to ${workspace}/** to indicate recursion in the current workspace

While using recursive includes saves you from having to list every include path individually, the process of resolving recursive includes can be resource and time intensive, especially for large projects.   

To better tailor this process to your project’s structure and your performance needs, you can now optimize with three new configuration options in c_cpp_properties.json:

1. recursiveIncludes.reduce

By default, the C++ extension avoids passing unneeded include paths to the IntelliSense process. When the extension opens and parses a source file, it recursively follows each #include to track every directory that contains a header. Only these relevant directories are used in the final configuration passed to the IntelliSense process. However, the process of identifying directories to reduce can add additional overhead. 

With the new “recursiveIncludes.reduce” setting, you can choose to skip this reduction step. By setting reduce to “never”, all recursive include paths will be passed to the IntelliSense process. In some situations, depending on the sub-directory layout, header file structure, and other project characteristics, this can lead to performance improvements. 

For example, when setting reduce to “never” for the PyTorch source code, there was an average 3.1x speedup in the time to generate the initial semantic colorization for a file on first open. For this project, it is faster to pass all include paths to the IntelliSense process rather than spend time reducing include paths to relevant directories.  This speedup was 1.5x on MacOS, 2x on Linux, and 5.8x on Windows. Testing was done using version 1.99 of VS Code, comparing the C++ extension version 1.23 to 1.25. 

  graph that shows the time to colorization in milliseconds between using reduce= always and reduce=never. for windows it went from 88.13 to 14.99 when switching to never. for mac it went from 32.6 to 21.89 switching from always to never. for linux it went from 74.42 to 37.4 switching from always to never.

Note that performance gains may vary depending on the machine and project used. To learn more, please reference the recursive include path documentation.

2. recursiveIncludes.priority

Have you ever opened a large project for the first time, opened a file that uses  #include “string.h” and IntelliSense finds the wrong string.h? It turns out one of your project’s sub directories contains a header file named “string.h” that conflicts with the system header for “string.h”. With the new priority setting, you can now determine which of these two to choose. 

Always prioritize your own header file? Choose “beforeSystemIncludes”.  This process mimics a compiler’s resolution order, which ensures IntelliSense results match the compiler’s results and allows for more predictability. For example, if you create a “string.h” locally, you probably want IntelliSense to pick up that file in the same way a compiler would. 

Always prioritize the system header? Choose “afterSystemIncludes”. For example, if your code contains the sysroots for multiple IoT devices, you want to pick up system includes from your compiler and not from the first sysroot found in your workspace.  

3. recursiveIncludes.order

Customize further by specifying the search order so relevant header files are found first. If your workspace has multiple files of the same name, and the incorrect file is chosen, try switching to “breadthFirst” instead of the default “depthFirst” so headers closer to the root of the recursive include path have higher priority.   

Try it out 

To experiment with these new settings and experience the performance improvements yourself, open your workspace in VS Code, then: 

  1. Open the Command Palette (Ctrl+Shift+P on Windows or Cmd+Shift+P on Mac) and open the editor for c_cpp_properties.json by running: `C/C++: Edit Configurations (JSON)`
  2. Confirm you’re using a recursive path ending in /** under “includePath”: 

same picture as the first one, just showing include path has the ?** at the end

      3. Add or modify the fields in the recursiveIncludes section:

screenshot of cpp properties.json that includes an example of every setting just discussed. reduce set to never, priority set to after system includes, and order set to breadthfirst 

Save your changes and reopen a file in your project to see them take effect. You can toggle these settings to determine which configuration provides the best performance for your project.  

What do you think?  

Download the C/C++ extension for Visual Studio Code  today, give it a try, and let us know what you think.  

If you have any questions around this release, feel free to start a discussion in our GitHub repository. Otherwise, if you run into any issues, please report them in the issues section. We can be reached via the comments below, per email at  visualcpp@microsoft.com, or through our team on X/Twitter at  @VisualC. 

 

The post VS Code C++ Extension 1.25 Release: Explain C++ symbols using Copilot & Customize recursive include paths appeared first on C++ Team Blog.

Previous Article

The MIT-Portugal Program enters Phase 4

Write a Comment

Leave a Comment

Your email address will not be published. Required fields are marked *