Visual Studio “15” Preview Compilers Feedback
Bring your C++ codebase to Visual Studio with “Open Folder”
Welcome to Visual Studio ’15’ Preview 5! Starting with this release, Visual Studio supports opening folders containing source code without the need to create any solutions or projects. This makes it a lot simpler to get started with Visual Studio even if your project is not an MSBuild-based project. The new functionality, “Open Folder”, also offers a more natural source file management as well as access to the powerful code understanding, editing, building and debugging capabilities that Visual Studio already provides for MSBuild projects.
This post describes the “Open Folder” support for C++ codebases. You will learn how to use “Open Folder” to easily:
- read C++ code
- edit C++ code
- build and debug C++
All this without having to create and maintain any .vcxproj or .sln files.
Getting started with “Open Folder” for C++
With the release of Visual Studio ’15’ Preview 5, we’re announcing the availability of C++ support for “Open Folder“. When you install the product, make sure to install one of the C++ workloads e.g. “Desktop development with C++” or “Game development with C++”.
If you have a CMake-based project, also read the blogpost describing our progress on the Visual Studio’s streamlined “Open Folder” experience for CMake. If your project is using another build system, read on.
To get the best experience in Preview 5, you need to create a small file called CppProperties.json in the folder you plan to open with the content below. Note: In future previews, creating this file will not be necessary (it will only be needed for the cases when you want to customize the default IntelliSense experience)
CppProperties.json:
{ configurations: [ { name: "Windows", includePath: [], defines: [ "_DEBUG" ], compilerSwitches: "/W3 /TP" } ] }
After that, all you have to do is run the “Open Folder” command and select the folder you want to browse (either from File > Open > Folder or through Quick Launch)
Reading C++ code
As soon as you open the folder, Solution Explorer will immediately display the files in that folder and you can open any files in the editor. In the background, Visual Studio will start indexing the C++ sources in your folder.
You now have access to all the Visual Studio capabilities of reading and browsing C++ code (e.g. Find all references, Go to symbol, Peek definition, Semantic colorization and highlighting, Class View, Call Hierarchy, to name a few).
Depending on the project, you may need to update the CppProperties.json file with more information about your source code e.g. additional include paths, additional defines or compiler switches. For example, if your project includes windows.h and friends from the Windows SDK (which is common), you may want to update your configuration file with these includes (using default installation paths for Preview 5):
CppProperties.json:
{ configurations: [ { name: "Windows", includePath: [ "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.10240.0\\ucrt", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.6.1\\include\\um", "C:\\Program Files (x86)\\Windows Kits\\8.1\\Include\\um", "C:\\Program Files (x86)\\Windows Kits\\8.1\\Include\\shared", "C:\\Program Files (x86)\\Microsoft Visual Studio\\VS15Preview\\Common7\\IDE\\VisualCpp\\Tools\\MSVC\\14.10.24516.00\\include" ], defines: [ "_DEBUG", "_WIN32" ], compilerSwitches: "/W3" } ] }
In general, the Error List window is a good starting point to review any IntelliSense errors caused by missing includes – filter its content to “IntelliSense only” and error code E1696:
Editing C++ code
All these C++ browsing and navigation services work without you having to create any Visual C++ projects like in previous Visual Studio releases (through the “Create Project from Existing Code” wizard).
As you create, rename or remove source files from your project, you don’t have to worry anymore about updating the Visual C++ projects as well – Visual Studio will rely on the folder structure and monitor changes on disk as needed. Also, when you edit code, Visual Studio’s IntelliSense will continue updating and assisting you with the latest information from your sources.
While editing your code, you can also use all of the refactoring features that Visual Studio supports for C++ e.g. Rename symbol, Extract function, Move definition location, Change signature, Convert to raw string literals, etc.
Building C++ projects
Building under “Open Folder” is not yet supported. Stay tuned for one of our upcoming releases for more information on this.
You will have to continue building your projects from a command prompt for now.
Debugging C++ binaries
To get started with debugging in Visual Studio, you want to navigate in Solution Explorer to your executable. Then right click, and select “Debug” – this will immediately start a debugging session for this executable.
If you want to customize your program’s arguments, select “Debug and Launch Settings” instead. This will create a new launch.json file pre-populated with the information about the program you have selected.
To specify additional arguments, just add them in the “args” JSON array as in the example below
launch.json:
{ "version": "0.2.1", "defaults": {}, "configurations": [ { "type": "default", "project": "CPP\\7zip\\Bundles\\Alone\\O\\7za.exe", "name": "7za.exe list content of helloworld.zip", "args": [ "l", "d:\\sources\\helloworld.zip" ] } ] }
As soon as you save this file, a new entry in the Debug Target dropdown will be available and you can select it to start the debugger. By editing the launch.json file, you can create as many debug configurations as you like, for any number of executables. If you press F5 now, the debugger will launch and hit any breakpoint you may have already set. All the familiar debugger windows and functionality is now available.
What’s next
Download Visual Studio ’15’ Preview 5 today and give “Open Folder” a try – no need to create VS projects and solution files anymore to become productive in VS.
This is an early preview and we’re continuing work on making this experience even better. In upcoming releasess, you will see us enhance the way the C++ browsing and navigation works, as well as supporting more debugger types, eventually reaching parity with our MSBuild-based project functionality. Your feedback is really important in informing our next steps so don’t hesitate to share it. We’re listening!
C++ compiler diagnostics improvements in VS “15” RC
This post written by Andrew Marino and Andrew Pardoe
Visual C++ in VS “15” RC now allows you to see where errors are in a line of code—the column number—as opposed to just showing the line number. As C++ has grown it’s increasingly useful to have a little more help finding your errors.
Consider this somewhat contrived example:
int f(int, int); int main() { return f(f(f(1, 2), f(3, 4), 5), f(6, 7)); }
Traditionally Visual C++ would just tell you t.cpp(6): 'f': function does not take 3 arguments
. With five different calls to f
on one line, it’s hard to figure out where your error is.
Providing column numbers helps greatly: t.cpp(5,32): error C2660: 'f': function does not take 3 arguments
. Now at least the compiler has identified which call to f
is incorrect.
But you can do more! You can now show the source context with the column information:
t.cpp(4,32): error C2660: 'f': function does not take 3 arguments return f(f(f(1, 2), f(3, 4), 5), f(6, 7)); ^
In this mode, the compiler doesn’t just tell you the column, it also points out the error with a caret.
Controlling diagnostics output
You can control the diagnostics format with a new compiler flag, /diagnostics:
. There are currently three arguments accepted: classic
, column
, and caret
.
classic
is the default, showing only the line number. We didn’t change the default because it’s often not a human reading the compiler’s output. Frequently a build system or some other program will be reading the output. In this scenario you want the output to be simple and easily parsed.column
provides the next level of information: the column where the error was encountered.caret
provides the richest level of information: the context of where the parser found the error and a caret (^) indicating where in the code the error was found.
Customizing output in Visual Studio
Controlling the diagnostic output in Visual Studio is as easy as selecting the level under C/C++ -> General options:
If you select either column
or caret
, clicking on the error in the error windows will bring the cursor to the column where the error was encountered. For example, the cursor is on the closing parentheses of the call to f
that erroneously includes three arguments. Parentheses highlighting (in light grey) shows the scope of the function arguments.
At the bottom of this screen you can see the “Col” column. This is off by default in the errors window. Right-clicking on the column headers brings up a dialog where you can select what columns are shown. Selecting the “Col” column allows you to see the column number.
Deleted special member function errors
We haven’t just improved diagnostics formatting—we’re making our diagnostics clearer and more helpful across the board. We’ve made improvements in areas such as static asserts, constexpr
, and special member functions.
Here’s an example where code references a deleted special member function. The compiler has generated a default constructor as a special member function. But because the developer supplied an explicit constructor, A(int)
, the compiler deleted the default constructor. Instantiating a variable with the type of the union that contains A
will result in an error to find the default constructor.
struct A { A(int); // non-trivial constructor }; struct B {}; // trivial constructor union variant { A a; B b; }; int main() { variant var; }
Previously the compiler would tell you the nature of the error:
source.cpp(16): error C2280: 'variant::variant(void)': attempting to reference a deleted function source.cpp(12): note: compiler has generated 'variant::variant' here
Now, it additionally tells you why the function was deleted and points you back at the source of the error:
source.cpp(16,1): error C2280: 'variant::variant(void)': attempting to reference a deleted function source.cpp(12): note: compiler has generated 'variant::variant' here source.cpp(12,1): note: 'variant::variant(void)': function was implicitly deleted because a data member 'variant::a' has either no appropriate default constructor or overload resolution was ambiguous source.cpp(10): note: see declaration of 'variant::a'
Looking ahead
There are many improvements we can make to our compiler diagnostics going forward. The perfect diagnostic would tell you exactly where your error is and how to fix it: we have a long way to go before we get to that point! But we’re committed to making improvements in the accuracy and completeness of our compiler diagnostics.
You may occasionally notice that the column information in a diagnostic is incorrect. This can happen because the code contains multiple-byte characters or because of a bug in the compiler’s parser. Because we’ve never displayed the column number there are a few places where we’ve recorded it incorrectly and haven’t yet found the error. Please let us know if you find a code sample where the diagnostic column information is incorrect!
There area also places where the compiler just won’t emit a column number, even though you’ve asked for columns. There are a couple of examples in the diagnostics above:
source.cpp(12): note: compiler has generated 'variant::variant' here ... source.cpp(10): note: see declaration of 'variant::a'
This happens because we don’t have column number information in all of our diagnostics. We’re working on expanding the coverage.
We know that we’ve got a long way to go before our diagnostics rival those of other popular C++ compilers. A lot of the 30+ year legacy of the Visual C++ compiler shows in our diagnostics quality. But this is a first step, and we’re committed to continuing the improvements.
Send us your feedback!
As always, we welcome your feedback. For problems, let us know via the Report a Problem option, either from the installer or the Visual Studio IDE itself. For suggestions, let us know through UserVoice. And you can always reach us through e-mail at visualcpp@microsoft.com.
C++ IntelliSense Improvements – Predictive IntelliSense & Filtering
IntelliSense is one of the most commonly used features in Visual Studio. With it, developers can write code more efficiently and learn more about their codebase at the same time. In a sense, IntelliSense is both a guide and a productivity feature. We understand the importance of having a powerful IntelliSense system which displays highly relevant results right when they are needed and which minimizes the time you need to spend thinking or typing as a developer. We have been collecting your feedback for C++ IntelliSense and are happy to announce two major improvements in Visual Studio “15” Preview 5: Predictive IntelliSense and IntelliSense Filtering.
Predictive IntelliSense uses contextual awareness to limit the number of results displayed in the IntelliSense dropdown list. Many of you have pointed out that the dropdown list can get quite long, necessitating a lot of scrolling. With Predictive IntelliSense, we employ type matching to give you results that match the expected type that you will usually need. In the simplest case, if you type int x = and invoke the IntelliSense dropdown, rather than seeing a giant list of all possible results, you will see only integers or functions returning integers. Predictive IntelliSense also excludes several different kinds of results in other cases where Visual Studio expects those kinds aren’t relevant. The result is a far more concise list. This feature is currently experimental and is turned off by default, but you can turn it on by going to Tools > Options > Text Editor > C/C++ > Experimental > Enable Predictive IntelliSense.
Of course, we understand that sometimes, Predictive IntelliSense might not work out and you might need to go back to the longer list. We always had a hidden keyboard shortcut built into Visual C++ which expands the list of IntelliSense results. By default, that shortcut is Ctrl + J. Ctrl + J was used in the past to do things like removing the accessibility filter, which hid private and protected members in Member List results. Now, if Predictive IntelliSense is on, invoking Ctrl + J removes the Predictive filter, going back to the list you are accustomed to from earlier releases. Pressing Ctrl + J again removes the accessibility filter from Member List results where relevant. We have also added a button ([+]) under the IntelliSense dropdown list which does the same thing as Ctrl + J. Hovering over the button gives you some useful tooltip information about what is being shown.
If you check the screenshot above, you will notice there are even more buttons under the dropdown list however. That is because we also added a set of IntelliSense Filters for different kinds of results which you can toggle based on your needs to narrow down the list:
- Variables and Constants
- Functions
- Types
- Macros
- Enums
- Namespaces
We only list the filter buttons relevant to your current IntelliSense session so you often won’t see all the buttons at once.
Send us your feedback!
Please try Preview 5 and these new IntelliSense features. We’re always interested in hearing what you think so we can improve Visual Studio. For C++ IntelliSense suggestions/ideas, please feel free to email me directly at aupopa@microsoft.com or post/upvote ideas on UserVoice. You can submit bug reports via Connect as well, and don’t forget, you can always Send a Smile or a Frown right from Visual Studio if that works better for you.
CMake support in Visual Studio
This article describes the current proof-of-concept support for CMake in Visual Studio. As we evolve the experience in upcoming preview releases, we will continue to update the content here.
What is CMake
CMake is a cross-platform open-source tool for managing build processes across multiple platforms by abstracting away native build environments and compilers. CMake interprets a CMake script the user authors and generates a build plan in a build environment of choice (e.g. in Visual studio projects, make scripts, Xcode projects, etc.).
Since the beginning, CMake had support for Visual Studio targeting and it has closely paired each release of Visual Studio with a CMake generator allowing users to target a long list of VS versions throughout the years. The latest version supports every version of VS starting with 2005 and up to our latest preview release VS ’15’.
CMake momentum and your feedback
CMake has seen a tremendous uptick in the C++ community in recent years across all platforms. In our developer surveys, we have seen CMake constantly grow in usage year over year since 2012, surpassing in 2015 the make family (make/gmake/nmake) in terms of adoption.
With so many of you starting to use CMake with Visual Studio, we heard a lot of feedback and we’ve been constantly thinking of ways to improve the VS experience for CMake users. In 2014, we’ve contributed support for generating Visual Studio C++ projects targeting Windows Store and Windows Phone and in 2015, we’ve contributed support for generating Visual Studio C++ projects targeting Android.
But that only scratched the surface of the feedback we’ve been hearing. There is only so much a command line tool — even one like CMake — can do to control the C++ IDE experience and we heard from many of you that:
- It is not obvious which IDE features apply to CMake projects and which get lost when regenerating the VS projects
- For developers new to CMake, CMake language has a steep learning curve and its generated MSBuild-based projects are difficult to diagnose
- The switch between command line (to invoke CMake) and IDE to write code creates friction, made worse by the need to generate separate solutions to target x86 or X64to target various architectures
- CMake regeneration of VS projects causes a non-elegant solution reload experience in VS that disrupts the coding experience. Solution reload required by CMake during build is even more aggravating.
- Solution Explorer’s view of the generated VS projects does not resemble the disk organization of the CMake projects making it hard to navigate
Visual Studio support for CMake
Two initiatives that started taking shape in early 2016 marked a turning point in our planning. By this time, we already knew we wanted to tackle this problem space but we weren’t sure yet how to fix many of the challenges we heard from you.
- The first initiative, in the CMake community, was the CMake-server prototype developed initially by Stephen Kelly to improve the tooling story for CMake. This started some interesting conversation in the CMake community as well as internally in our team and it was dubbed the missing link between CMake and the IDE.
- The second one, a Visual Studio initiative (“Open Folder”) designed to enable the developer inner-loop (edit-build-debug experience) without the existing VS solution & C++ project system infrastructure, allowing non-MSBuild C++ codebases to be loaded in Visual Studio in a folder-based experience. This is now part of Visual Studio ’15’ “Open Folder” C++ capability.
Visual Studio ’15’ Preview 5 is the first release where we use both functionalities in conjunction in a proof-of-concept implementation of our CMake support in Visual Studio. While it will not be something you can try with your own CMake projects yet — this is coming in a future preview –, the current implementation tells us a lot about the underlying technologies and we’re more confident now that with future previews, we can deliver a solid CMake integration. VS can now:
- Enumerate CMake targets and files for each target,
- Detect outputs for CMake targets,
- Collect compiler switches including default system paths for files,
- Configure, build and install CMake scripts,
- Detect changes in CMakeLists.txt and dependents and reconfigure automatically
- All without needing a dedicated CMake generator
What’s next
Moving forward we will continue building on this functionality — stay tuned for a future preview in which you can try the VS support with your own CMake project. For now, if you want to experiment with our early prototype start with the example below and watch the CMake demo in our Visual Studio talk “Latest and Greatest from the Visual Studio Family for C++ developers” at CppCon.
CMakeLists.txt
cmake_minimum_required (VERSION 3.6) project (hello-world) add_executable(hello-world hello.cpp) install(TARGETS hello-world DESTINATION bin)
Hello.cpp
#include <iostream> #include <Windows.h> int main(int argc, char* argv[]) { std::cout << "Hello" << std::endl; }
The list of possible operations is available by right clicking on the CMakeLists.txt in Solution Explorer: Build, Clean, Install and Debug.
Visual C++ Compiler Version
This blog was written by Gabriel Dos Reis and Mark Levine.
Starting with VS “15” Preview 5, the Visual C++ Team is monotonically updating the value of the built-in preprocessor macro _MSC_VER
at every Visual C++ toolset update.
Why?
Thanks to the investments and progress that the Visual C++ Team has been making in the area of ISO C++ implementation conformance, we have been shipping new language features and introducing new conformance changes at a pace never seen before by our customers, in particular in updates to the Visual C++ toolset. As a result, it has become necessary for our customers to have a good way to differentiate between updates of VC++ (and not just major versions) within their source code. For instance, a program wanting to make use of the C++11 noexcept feature with VC++ would typically write:
#if _MSC_VER >= 1900 // … use noexcept here … #endif
How to Test?
Traditionally, developers write conditionally-included pieces of code testing the value of the built-in preprocessor macro _MSC_VER
against known values indicating major releases of the Visual C++ compiler. For example,
_MSC_VER >= 1900
tests for any version of the Visual C++ compiler released after VS2015 RTM. That continues to be our recommended practice. What we are doing, starting with VS “15”, is to increment the value of _MSC_VER
at each update.
To test for VC++ updates or releases after a given reference point, use the “>=
” (greater-or-equal) operator to compare _MSC_VER
against that known reference value. Furthermore, if you have several reference points to compare against in a mutually exclusive manner, we recommend you order your comparisons in decreasing order of the reference values. For instance, the following snippet
#if _MSC_VER >= 1900 // … #elif _MSC_VER >= 1800 // … #else // … #endif
checks for compilers released after VS2015, then compilers released after VS2013, then takes an action for all compilers released prior to VS2013.
Ordering Tests with <
If you chose to use the less-than operator (<
), then we recommend that you order your tests in increasing order of the reference values.
Checking for A Specific Compiler Version
On very rare occasions, you might be looking for a specific VC++ release. Only in such circumstances would you need to use the equality operator “==
” to compare _MSC_VER
against a known value. Such circumstances include working around a bug in a well-known version of VC++. However, in general, we recommend you use the “>=
” and order your tests in decreasing order.
Looking for A Closed Set of Compiler Versions
Some circumstances require looking for a closed set of compiler versions. For instance, this code fragment
#if _MSC_VER >= 1900 && _MSC_VER < 2000 “mspdb140.dll” #endif
includes the string literal “mspdb140.dll”
only when the compiler is from the VS2015 vintage. In these situations, you will use “>=
” and “<
” to construct a semi-open interval that delimits the release series you are interested in.
When Should I Use _MSC_FULL_VER Then?
_MSC_FULL_VER
is a more granular variant of the built-in preprocessor macro _MSC_VER
that incorporates also the build number of the compiler. You would use this when you want to differentiate between micro-updates of the same update. Until now, it has also been used to differentiate between updates.
What About _MSC_BUILD?
It is a built-in preprocessor macro, documented here, rarely used or needed in most C or C++ source code.
The Compiler Versioning Scheme
Each major release of the Visual C++ compiler increments the “hundreds” of _MSC_VER
. Each update within a major release increments the “units” by 1. For example, in VS “15” Preview 5, the macro _MSC_VER
evaluates to 1910. The next update will have _MSC_VER
set to 1911.
Note that VS “15” and VS2015 are both major releases of Visual Studio with different major version numbers. The included compiler toolset, however, will have the same major version number – with the change described here, the minor version number can be used to distinguish compiler toolsets.
Call to Action
If you have existing code that compares _MSC_VER
using the equality operator, have a second look and see if that comparison is better expressed with the greater-or-equal operator as explained above.
Visual Studio “15” Preview 5 Now Available
Visual Studio “15” Preview 5 is now available. Read the official announcement on the Visual Studio blog.
Highlights for C++ developers include:
- Faster project load, coding, and debugging for C++.
- The C++ Core Checkers for enforcing the C++ Core Guidelines are now distributed with Visual Studio.
- Enhanced support for C++11 and C++14 features, as well as preliminary support for certain features expected to be in the C++17 standard. This release includes complete support for generalized constexpr.
- Improvements, fixes and additions to the Standard Template Library.
- Enhanced C++ code generation of loops and C++ code security.
- IntelliSense Filters and Experimental C++ Predictive IntelliSense pare another way to narrow down the results in the list by specific kinds.
- Navigate To (now known as Go To) and Find All References have been overhauled to improve the code navigation experience
- The popular extension Visual C++ for Linux Development is now part of Visual Studio.
- C++ support in “Open Folder” as well as proof-of-concept CMake support.
- And more…
For the complete list of everything in this release, along with some known issues, look at the Visual Studio “15” Preview 5 Release Notes page. The Preview 5 FAQ provides answers for common questions.
As always, we welcome your feedback. Try the report a problem feature in the IDE to share feedback on Visual Studio and check out the developer community portal view. If you are not using the Visual Studio IDE, you can report issues using the Connect Form for reporting issues.
For suggestions, let us know through UserVoice.
We look forward to your feedback.
Faster C++ solution load with VS “15”
The Visual C++ product has had projects ever since its inception. Visual C++ had its own IDE up through Visual Studio 6. Starting in Visual Studio .NET, C++ moved to a new IDE shared by Visual Basic, C#, C++, and other tools. This new IDE used COM everywhere and items in the Solution Explorer were based on IVsHierarchy. Much of the existing project system was kept intact but it was exposed through a new set of COM objects that implemented IVsHierarchy and other interfaces.
In Visual Studio 2010, the underlying project/build system was changedfrom VCBuild to MSBuild. This is also when the file extension changed from .vcproj to. vcxproj. At this point, the existing set of (relatively new) COM objects was kept, but forwarded into a new set of managed “shim” objects that then called into the new project system. This new project system eventually became known as the Visual Studio Project System (VSPS).
As years went by, developers created ever larger solutions and projects. This created a problem as Visual Studio took longer and longer to load these ever-increasing solutions. Each project would get parsed and a large graph of objects would be created in memory and kept there. At least one object per node in the hierarchy would get created. This approach takes a lot of time and uses a lot of memory. Visual Studio tried to keep up and has implemented various strategies to support large projects. For instance, you can explicitly unload projects to prevent them from getting loaded and ASL (Asynchronous Solution Load) was introduced in Visual Studio 2013. ASL tries to load most projects on a background thread and make the UI immediately responsive for other tasks.
While ASL works to a large extent, we have heard from many developers that they prefer to just wait for the whole solution to finish loading and all other background work to finish before trying to use the IDE. You know, open your solution and go get coffee.
Even after all of the projects are loaded, there is still other stuff happening that is using CPU and disk. In the status bar, you are probably used to seeing the following:
This message means we are doing what we call a “design-time build”. The VSPS is evaluating projects and figuring out what would be built and how it would be built. We do this to generate command-lines for every file in every project and then compare them to what we have stored in the browse database. If they have changed, we write them into the database. The command lines are used for Intellisense and also to resolve include files that are indexed in the browse database.
After this “initializing” phase you will see that we are checking for out-of-date files (and then updating them if needed). Finally, the status bar shows ready. However, if you take a look in Task Manager, you will notice that one CPU is still getting heavily used. In the background, we are still doing work. The first task is populating the “external dependencies” node of each project. This node contains files that aren’t explicitly in the project but are #included directly or indirectly by some file in the project. After this step, there is one more invisible step which checks the database for orphaned records, such as files we indexed that aren’t used anymore (directly or indirectly) by any project. All of this happens every time you open a solution even if absolutely nothing has changed since the last time you used it.
Let’s take a look at loading the Chromium solution and see how long each of these steps is taking in Visual Studio 2015 Update 3 vs. Visual Studio 15 Preview 5. If you follow the instructions on the Chromium website, the solution is generated by the command “gn gen –ide=vs out\Default”. This results in ~4600 projects of which ~1000 are “Solution Folders” and the others are .vcxproj projects.
The following results are on Windows 10 from my personal machine which is an Intel Core i7-4790 @ 3.6GHz and two SSDs: one as system drive and one for source code (Samsung 850 Pro). The first set of results is in Visual Studio 2015 Update 3 and the second set is from Preview 5 of Visual Studio 15.
We realize that the “parsing/resolving includes” phase is about 25% slower than in VS2015 Update 3. We are working on improving this as well and expect to get that resolved soon.
Why is solution load with Visual Studio “15” so much faster?
Because of our existing layered architecture, it was relatively easy to insert a new caching layer that can answer many questions about projects and configurations without having to actually load the project into the VSPS. This new layer uses a SQLite database to quickly retrieve information on demand.
When a solution is loaded and we are asked to load a C/C++ project, we get a list of all .vcxproj files this solution will load. We check the database to see if we already have these projects and if any files have changed. If we need to update the information about a set of projects, those projects are put into a queue. That queue is handled by multiple external processes that use MSBuild to load the projects and collect information about them and write it to the database.
As we are asked to load each project, we create a set of small shim objects that can service many requests without needing to fully load a project. We can provide all of the information that our Intellisense engine needs, as well as provide what Solution Explorer needs through information in the database. If an API is called that needs a real project (such as modifying project settings), the underlying shim will load the project on the fly and delegate to it.
Because of this change the load time of individual projects went way down, but not as low as we desired. Profiling revealed some pretty bad algorithms with N^2 time complexity in various places. Our memory use also dramatically dropped after this change, but we also found some pretty bad memory use inside our own objects. We were able to trim the size of each object that represents a file in a solution (including external dependencies) from 120 bytes to 44 bytes per instance. It may not seem like much, but some large solutions end up with millions of these objects. We are still working on improving the performance of project load and I expect to see some additional improvements before shipping the final version.
This feature is truly experimental, there are still some issues with fast project load we want you to be aware of.
- Projects that need upgrading should be upgraded first before trying to use fast project load on them as upgrade will not happen during FPL.
- Our story today for being able to build is not complete for this preview release. Very simple solutions with one project might build but that’s pretty much it.
- Projects will load through VSPS on demand such as when explicitly editing a project (e.g. adding files or changing properties). A large
project may take a few seconds to load. We want to signal this to the user but we haven’t yet in all cases. - Third party plugins could choose to walk the entire solution hierarchy asking for properties that causes all projects to be fully loaded in VSPS, effectively defeating any benefits of FPL.
The IDE’s Output Window will display a message whenever a project is fully loaded into the VSPS. Please let us know if you see these messages unexpectedly.
Lightweight Solution Load
There is another experimental effort underway in Visual Studio to improve solution load called “lightweight solution load”. This is a completely different approach and you can read about it here. Generally, it will avoid loading projects at all and will only load a project when a user explicitly expands a project in Solution Explorer. The C++ team has been focused on Fast Project Load and so our support for lightweight solution load is currently minimal. In the RC release of Visual Studio 15, we expect to support FPL in conjunction with Lightweight Solution Load. This combination should provide a great experience.
Wrap Up
As always, we welcome your feedback and we would love to learn from your experiences as you try these features out. Do let us know if you run into any issues trying out faster solution load through report a problem tool.
You can also email us your query or feedback if you choose to interact with us directly! For new feature suggestions, let us know through User Voice.
Faster C++ build cycle in VS “15” with /Debug:fastlink
Continuing with our goal of further improving developer productivity with Visual Studio “15” there have been major investments made for also improving incremental developer builds. The developer incremental build is one where a developer changes a single or multiple source files and builds. The time spent in these builds is almost equal to the time spent in linking the binaries. With Visual Studio 2015 we introduced a new linker switch ‘/debug:fastlink’. With ‘/debug:fastlink’ developers on average see an improvement of 2-4x in clean link times.
So why is /debug:fastlink so much faster for link times?
Well, with /debug:fastlink the linker-produced PDB doesn’t have any private symbol information. Debug information is distributed among input object and library files, and the linker PDB just serves as an indexing database. While this provides a huge performance benefit for the daily developer builds, there is one scenario you will need to handle differently, and that is when you want to share the linker PDB with another developer on the team or upload the linker PDB’s directly to symbol server. There have been requests for tooling which is able to create a full PDB from the /debug:fastlink PDB on demand and with this release we are doing just that. Developers will now be able to generate a full PDB from a /debug:fastlink PDB both at a solution, project level using the new options shown in the figures below:
/Debug:fastlink now default setting for new and existing projects (Debug Configuration)
Another issue with using /debug:fastlink is its lack of discoverability and today developers need to play around with linker property pages to discover this feature. Starting with Visual Studio ‘15’ /debug:fastlink will serve as the default program database file generation setting for new project templates.
In addition to changing the default setting for program database file generation, with this release we are also changing the definition of the existing program database generation linker flag:‘/debug’ to map to ‘/debug:fastlink’ for the ‘Debug’ configuration in Visual Studio.
This will allow us to migrate all existing Visual Studio developers to use /debug:fastlink by default. Developers can opt-out of this behavior by adding the ‘/debug:full’ linker switch to linker command line or by enabling the ‘Generate Full Program Database File’ as shown in the property page below.
We missed the opportunity to unify ‘Generate Debug Info’ and ‘Generate Full program Database File’ for this setting but will be doing so for the upcoming release.
Another thing we would like to share on this front is that in Visual Studio “15” we are working on further improving /debug:fastlink by moving name hash building from link time to DIA (or debug) time. There is a small increase in time taken for first name lookup related debugging actions (like function/data lookup by name for expression evaluation in watch windows) but it’s only noticeable for very large binaries (>50 Mb). The figure below highlights the link time improvements you will obtain with /debug:fastlink over /debug in the next update for Visual Studio “15”.
Wrap Up
As always, we welcome your feedback and we would love to learn from your experiences as you try these features out. Do let us know if you run into any issues trying out /debug:fastlink or fail to see any link speed improvements. You can also email us your query or feedback if you choose to interact with us directly! For new feature suggestions, let us know through User Voice.
Compiler Tools Layout in Visual Studio “15”
This post was written by Andrew Pardoe, Mark Levine, and Iyyappa Murugandi.
You’ll see many improvements for C++ developers in Visual Studio “15” as soon as you load your first project. But some of the changes in the product aren’t so obvious. One in particular might surprise you: we’ve moved where the MSVC compiler toolset is laid out on disk.
Why we moved the compiler toolset
The layout of the compiler tools on the disk in VS 2015 reflects decisions made years ago. When we shipped Visual Studio .NET in 2002, we shipped compilers that targeted only the x86 architecture. The x64 and Itanium architectures had only recently been announced when development of Visual Studio .NET started. The layout of the compiler on-disk reflected a world where x86 was the only compiler you would need.
When we introduced support for the Itanium and x64 architectures we added the compilers where it made sense: in the bin
directory. We already had a compiler for x86 in the bin
directory, so we added subdirectories x86_ia64
and x86_amd64
for compilers that run on x86 and target 64-bit platforms as well as an amd64
directory for compilers that run on x64.
Unfortunately, it didn’t stop there. We added compilers for ARM. And we added cross-targeting compilers that are hosted on x64 and target x86 and ARM. Eventually we ended up with a directory tree that made little sense. Every time a developer wants to write automation that deals with our compilers they have to write special cases in their scripts for the x86 hosted and targeting compiler. Moreover, this layout limits our ability to do interesting things such as having two versions of a compiler or two different compilers installed side-by-side on the one build machine.
Where the compiler toolset moved to in VS “15”
First, let’s discuss the major parts of the compiler toolset. These are reflected in the top-level directory, e.g., %ProgramFiles(x86)%\Microsoft Visual Studio\VS15Preview\Common7\IDE\VisualCpp
. (Note that this directory, %VCINSTALLDIR%
, changed from its VS 2015 location of %ProgramFiles(x86)%\Microsoft Visual Studio 14\VC
.)
- Tools: The tools are what you traditionally think of as the MSVC compiler toolset. This includes the old bin, crt, include, and lib directories and the binaries that are placed in them. These binaries include cl.exe and link.exe as well as header files and link libraries for the Visual C++ runtime.
- Redist: The redistributable directory contains files that can be redistributed by the end developer with the built application. The CRT redistributables are located here, as well as the other runtimes such as those for AMP and OpenMP.
- Auxiliary: The auxiliary directory contains tools and scripts that are not part of the compilation process but are needed to help with various compilation scenarios. These include files like the CppCoreCheckers or the Unit Test libraries as well as the
vcvars*.bat
scripts used to configure developer environments.
Note that the compiler toolset layout in Preview 5 is just that–a preview. We may end up changing the layout or even the top-level %VCINSTALLDIR%
directory depending on feedback and requirements from internal and external developers.
The tools directory
Let’s take a closer look at the Tools directory–the directory contains the compiler toolsets. Unlike in VS 2015, the Microsoft Visual C++ compiler is in a directory called MSVC
. If you installed the “Clang with Microsoft Codegen” option, you’ll see a directory next to MSVC
called ClangC2
that contains the Clang/C2 binaries.
There’s a subdirectory in the MSVC directory with a compiler version number. For Preview 5, that version number is 14.10.24516.00. In that directory are the familiar subdirectories from the %VCINSTALLDIR%
directory in VS 2015: bin
, crt
, include
, and lib
.
We’ve encountered two big differences so far. First, the MSVC
directory means that the Visual C++ tools can sit beside another toolset, in this instance, ClangC2
. Second, the fact that the tools are versioned inside of the MSVC
directory means that we can have multiple versions of the Visual C++ compiler installed on the same build machine. Right now, there’s no simple way to install multiple versions. But we’ve designed the directory structure to make it possible in the future to easily switch between versions of the Visual C++ tools.
Hosts and targets
We find even more changes when looking inside the 14.10.24516.00\bin
directory. While in VS 2015 the x86 toolset was the “standard” toolset and we had directories with names like amd64_arm
representing the AMD64-ARM cross-targeting compiler, in VS “15” these have been split up into directories labelled HostXXX
and a subdirectory called x86
or x64
. What’s the distinction here?
Let’s pause to define a couple of terms. “Host” refers to the platform that the compiler toolset runs on. “Target” refers to the platform that the compiler builds applications to run on. In the VS 2015 world, amd64_arm
included the compilers that were hosted on x64, and targeted ARM. In VS “15” it’s more structured: all of the x64 hosted compilers live in a directory called HostX64
. In that directory we find x86
, x64
, etc., indicating the target architecture.
The bin
directory is the only one with a set of HostXXX
directories. This is because the executables need to run on the host. The include
directory, which contains only source files, is specific to neither the host nor the target. The lib
directory is specific to only the target architecture. Likewise, many of the tools in the Auxiliary
directory are specific to the target architecture but not to the host.
Benefits of the new layout
We hope you can see that there are a lot of benefits to refreshing our compiler toolset layout on disk. As Visual C++ grows to include more scenarios like Android and iOS targeting we need to include more compiler toolsets. And as we release our tools more frequently we increase the chance that our developers might want to have multiple versions of the Visual C++ compiler tools installed side-by-side. This new layout is flexible and extensible and should (hopefully!) serve us for many years to come.
As in VS 2015, the Windows SDKs are not installed alongside the Visual C++ binaries, headers and libs. They are installing in the same location under the Program Files(x86)
directory. Visual C++ SDKs (such as the DIA SDK) will continue to be installed alongside the VC++ toolset.
Drawbacks of the new layout
Even though change can be good, it’s still change. We know that a lot of people have scripts that are going to break with this layout change. We decided to do this with VS “15” as we also had to change the top-level directory to accommodate restrictions with the new installer. But any change can be a breaking change.
Please, please, please check out the scripts that you use and make sure you can migrate them to use the new layout. We want to know if you run into any problems. We want to know how hard the migration experience was for your code. Please leave comments on this blog post or send mail directly to our team at visualcpp@microsoft.com.
Finding the default MSVC tools
One last note: a lot of build systems need to find the default version of the Visual C++ tools. When you install Visual Studio it creates a file, %VCINSTALLDIR%\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt
, that contains the version string for the default toolset installed with VS. In a typical Preview 5 installation, %VCINSTALLDIR%
would point to %Program Files(x86)%\Microsoft Visual Studio 15.0\Common7\IDE\VisualCpp
.
You can parse this file with one extra line and variable in your command script:
@rem set BINDIR=get directory for x86-hosted, x86-targeting binaries set /P VCTOOLS_VERSION=<"%VCINSTALLDIR%\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt" set BINDIR=%VCINSTALLDIR%\Tools\MSVC\%VCTOOLS_VERSION%\bin\HostX86\x86
Feedback
You’ll see a number of benefits from the new layout of the compiler toolset but we know that a lot of you will have to fix up scripts that you might not have looked at for years. We’re working on making this experience simple and smooth for everyone so please do reach out to us with details of your experience. If you have feedback on any part of this design please let us know in the comments below or by mailing visualcpp@microsoft.com. Thank you!
C++14/17 Features and STL Fixes in VS “15” Preview 5
Visual Studio “15” Preview 5 is now available. (As our previous changelog explained, VS “15” is an IDE version number, not a year. It’s the next major version after VS 2015, which was IDE version 14. VS has different numbers for its year branding, IDE version, and C++ compiler version.)
Preview 5 adds support for C++14 extended constexpr, unconditional support for generalized range-for (it’s a C++17 change that’s been determined to fix a defect in C++14), and support for C++17’s terse static_assert, shared_ptr::weak_type, <optional>, and <variant>. As usual, we’ve fixed many compiler bugs and library bugs, and we’ve resolved 10 more Library Issues.
Additionally, the VS “15” Release Candidate will add support for C++17’s <any>, <string_view>, apply(), and make_from_tuple(). It will also contain a major overhaul of std::vector for correctness and performance. While we’re still working on releasing VS “15” RC, you can try our daily toolset builds right now. Please report any bugs you find, in either Preview 5 or the daily toolset builds.
Compiler Features
C++03/11 Core Language Features |
VS “15” |
Notes |
[Everything else] |
Yes |
[A] |
Two-phase name lookup |
No |
|
Partial |
[B] |
|
Partial |
[C] |
|
N/A |
[D] |
|
C++14 Core Language Features |
VS “15” |
Notes |
N/A |
[E] |
|
Yes |
||
Yes |
||
Yes |
||
Yes |
||
Yes |
||
Yes |
||
Yes |
[P5] |
|
Yes |
[P4] |
|
Yes |
||
Yes |
||
Yes |
||
C++17 Core Language Features |
VS “15” |
Notes |
Yes |
||
Yes |
[P5] [*] |
|
Yes |
||
Yes |
||
Yes |
[*] |
|
No |
||
Yes |
||
Yes |
||
No |
||
No |
||
No |
||
No |
||
No |
||
No |
||
No |
||
No |
||
No |
||
No |
||
No |
||
No |
||
Yes |
[P5] |
|
Yes |
[P4] [*] |
|
No |
||
No |
||
No |
||
No |
||
No |
||
No |
||
No |
||
No |
||
No |
||
No |
||
No |
||
No |
||
No |
||
No |
||
No |
||
No |
[A] This is deliberately ignoring C++03’s dynamic exception specifications, which were deprecated in C++11. We aren’t planning to implement them, and hopefully they’ll be removed from a future C++ Standard.
[B] The compiler’s support for Expression SFINAE is continuing to improve (and has been sufficient for the STL since VS 2015 Update 2), but remains Partial. We’ll publish a detailed blog post about this in the near future.
[C] The compiler’s support for C99 Preprocessor rules remains Partial. Variadic macros are supported, but there are many bugs in the preprocessor’s behavior. We’ll overhaul the preprocessor before marking this as Yes.
[D] This is marked as Not Applicable because compilers are permitted, but not required, to support extended integer types. Like GCC and Clang, we’ve chosen not to support them.
[E] Similarly, this is marked as Not Applicable because compilers are permitted, but not required, to implement this optimization.
[P4] Implemented in VS “15” Preview 4.
[P5] Implemented in VS “15” Preview 5.
[*] These features are guarded by the /std:c++latest compiler option.
STL Features
Status |
Std |
Paper |
Title |
missing |
C++17 |
has_unique_object_representations |
|
missing |
C++17 |
C11 Standard Library |
|
missing |
C++17 |
hypot(x, y, z) |
|
missing |
C++17 |
Rewording enable_shared_from_this |
|
… |
C++17 |
Library Fundamentals V1 |
|
missing |
C++17 |
… |
<memory> shared_ptr<T[]>, shared_ptr<T[N]> |
missing |
C++17 |
Emplace Return Type |
|
missing |
C++17 |
Splicing Maps And Sets |
|
missing |
C++17 |
constexpr For <array> (Again) And <iterator> |
|
missing |
C++17 |
atomic::is_always_lock_free |
|
missing |
C++17 |
not_fn() |
|
patch |
C++17 |
Fixes For not_fn() |
|
missing |
C++17 |
gcd(), lcm() |
|
missing |
C++17 |
hardware_destructive_interference_size, etc. |
|
missing |
C++17 |
Elementary String Conversions |
|
missing |
C++17 |
… |
<algorithm>/<functional> Boyer-Moore search() |
patch |
C++17 |
Fixing Searcher Return Types |
|
missing |
C++17 |
Deprecating Vestigial Library Parts |
|
missing |
C++17 |
Removing Allocator Support In std::function |
|
missing |
C++17 |
Extending Memory Management Tools |
|
missing |
C++17 |
… |
<memory_resource> |
patch |
C++17 |
Deleting polymorphic_allocator Assignment |
|
missing |
C++17 |
Parallel Algorithms |
|
patch |
C++17 |
Renaming Parallel Execution Policies |
|
patch |
C++17 |
Parallel Algorithms Should terminate() For Exceptions |
|
missing |
C++17 |
Mathematical Special Functions |
|
missing |
C++17 |
<filesystem> |
|
patch |
C++17 |
Relative Paths For Filesystem |
|
patch |
C++17 |
Supporting string_view In Filesystem Paths |
|
doomed |
C++17 |
Ordered By Default |
|
RC |
C++17 |
… |
<any> |
RC |
C++17 |
… |
<string_view> |
RC |
C++17 |
… |
<tuple> apply() |
RC |
C++17 |
make_from_tuple() |
|
RC |
C++17 |
Integrating string_view And std::string |
|
Preview 5 |
C++17 |
… |
<optional> |
Preview 5 |
C++17 |
Homogeneous Interface For variant/any/optional |
|
Preview 5 |
C++17 |
<variant> |
|
Preview 5 |
C++17 |
shared_ptr::weak_type |
|
Preview 5 |
C++17 |
Making Optional Greater Equal Again |
|
Preview 5 |
C++17 |
Making Variant Greater Equal |
|
Preview 4 |
C++17 |
… |
<algorithm> sample() |
Preview 4 |
C++17 |
is_callable, is_nothrow_callable |
|
Update 3 |
C++17 |
clamp() |
|
Update 3 |
C++17 |
is_swappable, is_nothrow_swappable |
|
Update 3 |
C++17 |
Non-const basic_string::data() |
|
Update 2 |
C++14 |
SFINAE-Friendly result_of |
|
Update 2 |
C++17 |
Improving pair And tuple |
|
Up2 Win7+ |
C++17 |
shared_mutex (Untimed) |
|
Up2 opt-in |
C++17 |
Removing Deprecated Iostreams Aliases |
|
Update 2 |
C++17 |
Variable Templates For Type Traits (is_same_v, etc.) |
|
Update 2 |
C++17 |
as_const() |
|
Update 2 |
C++17 |
Logical Operator Type Traits (conjunction, etc.) |
|
Update 2 |
C++17 |
owner_less<> |
|
Update 2 |
C++17 |
<chrono> floor(), ceil(), round(), abs() |
|
Update 2 |
C++17 |
Variadic lock_guard |
|
VS 2015 |
C++14 |
constexpr For <complex> |
|
VS 2015 |
C++14 |
constexpr For <chrono> |
|
VS 2015 |
C++14 |
constexpr For <array> |
|
VS 2015 |
C++14 |
constexpr For <initializer_list>, <tuple>, <utility> |
|
VS 2015 |
C++14 |
integral_constant::operator()() |
|
VS 2015 |
C++14 |
UDLs For <chrono>, <string> (1729ms, “meow”s, etc.) |
|
VS 2015 |
C++14 |
Null Forward Iterators |
|
VS 2015 |
C++14 |
quoted() |
|
VS 2015 |
C++14 |
Heterogeneous Associative Lookup |
|
VS 2015 |
C++14 |
integer_sequence |
|
VS 2015 |
C++14 |
shared_mutex (Timed) |
|
VS 2015 |
C++14 |
exchange() |
|
VS 2015 |
C++14 |
Fixing constexpr Member Functions Without const |
|
VS 2015 |
C++14 |
get<T>() |
|
VS 2015 |
C++14 |
Dual-Range equal(), is_permutation(), mismatch() |
|
VS 2015 |
C++14 |
Sized Deallocation |
|
VS 2015 |
C++14 |
UDLs For <complex> (3.14i, etc.) |
|
VS 2015 |
C++14 |
constexpr For <functional> |
|
VS 2015 |
C++14 |
tuple_element_t |
|
VS 2015 |
C++14 |
Renaming shared_mutex (Timed) To shared_timed_mutex |
|
VS 2015 |
C++17 |
void_t |
|
VS 2015 |
C++17 |
Safe Conversions In unique_ptr<T[]> |
|
VS 2015 |
C++17 |
invoke() |
|
2015 opt-in |
C++17 |
Removing auto_ptr, random_shuffle(), And Old <functional> Stuff |
|
VS 2015 |
C++17 |
noexcept Cleanups |
|
VS 2015 |
C++17 |
uncaught_exceptions() |
|
VS 2015 |
C++17 |
Trivially Copyable reference_wrapper |
|
VS 2015 |
C++17 |
insert_or_assign()/try_emplace() For map/unordered_map |
|
VS 2015 |
C++17 |
size(), empty(), data() |
|
VS 2015 |
C++17 |
Precisely Constraining unique_ptr Assignment |
|
VS 2015 |
C++17 |
bool_constant |
|
VS 2013 |
C++14 |
Minimal Container Element Requirements |
|
VS 2013 |
C++14 |
Transparent Operator Functors (less<>, etc.) |
|
VS 2013 |
C++14 |
Alias Templates For <type_traits> (decay_t, etc.) |
|
VS 2013 |
C++14 |
make_unique() |
|
VS 2013 |
C++17 |
Supporting Incomplete Types In vector/list/forward_list |
|
N/A |
C++14 |
Discouraging rand() |
|
N/A |
C++17 |
Contiguous Iterators |
|
N/A |
C++17 |
Synopses For The C Library |
|
N/A |
C++17 |
Reserving Namespaces For Future Standardization |
|
N/A |
C++17 |
A <random> Nomenclature Tweak |
|
N/A |
C++17 |
Discouraging memory_order_consume |
This table is somewhat complicated; we use it to track our work, so it has to be detailed enough to tell us what to do.
“…” indicates where the Library Fundamentals V1 paper has been decomposed into its individual features.
“missing” means not yet implemented. We’re working on it! We were fully caught up in January, but then more features got voted in.
“patch” indicates where a feature was voted in, and then a paper fixing that feature somehow was also voted in. We’ll implement them together, so they don’t really represent any additional work for us to do. (Each patch is grouped below its affected feature.)
“doomed” indicates that the Ordered By Default feature has been found to break ABI compatibility (in other compilers), will not be implemented by any vendor, and will be removed from C++17.
“N/A” papers aren’t actually features – they altered Standardese, but didn’t create any work for implementers. They’re listed for completeness.
“VS 2013” indicates features that were supported long, long ago, in a compiler far, far away.
“VS 2015” indicates features that were supported in VS 2015 RTM.
“Update 2” and “Update 3” refer to VS 2015.
“Preview 4” and “Preview 5” refer to VS “15”.
“RC” indicates features that have been checked into VS “15”, but not in time for the Preview 5 build. They’ll be available in the Release Candidate build.
Note that while we’ve implemented the Filesystem TS (and for historical reasons we’re providing it as both <experimental/filesystem> and <filesystem>), we need to overhaul its implementation before moving around its namespace and marking the Standard feature as implemented.
STL Fixes in VS “15” Preview 5
Fixed silent bad codegen for stateful user-defined allocators requesting propagate_on_container_copy_assignment and propagate_on_container_move_assignment.
Added <cstdalign>.
Improved weak_ptr::lock() performance.
Fixed std::promise’s move assignment operator, which previously could cause code to block forever (VSO#243880/Connect#2972781).
Fixed compiler errors with atomic<T *>’s implicit conversion to T * (VSO#257598).
pointer_traits<Ptr> now correctly detects Ptr::rebind<U>.
Fixed a missing const qualifier in move_iterator’s subtraction operator.
atomic<T> now tolerates overloaded operator&() (VSO#198738).
Slightly improved compiler diagnostics for incorrect bind() calls (VSO#246001, reddit)
Simplified unique_ptr::operator->() (VSO#239517/Connect#2918170).
Changed the container adaptors to have implicitly defined copy/move constructors (VSO#234651).
To increase compiler throughput, STL headers now avoid including declarations for unnecessary compiler intrinsics (VSO#221287, requested by Clang and Chromium devs). This is inherently a source breaking change. If your code was assuming that <vector> or other STL headers drag in <intrin.h>, the mega-header providing declarations of compiler intrinsics, this assumption has been broken. Now we include a sub-header with just the intrinsics that we need to make shared_ptr and atomic work. If you encounter compiler errors, the fix is simple: include <intrin.h> directly.
Library Issues
Status |
Std |
Title |
|
missing |
C++17 |
LWG 1169 |
num_get not fully compatible with strto* |
missing |
C++17 |
LWG 2059 |
C++0x ambiguity problem with map::erase |
missing |
C++17 |
LWG 2156 |
Unordered containers’ reserve(n) reserves for n-1 elements |
missing |
C++17 |
LWG 2408 |
SFINAE-friendly common_type / iterator_traits is missing in C++14 |
missing |
C++17 |
LWG 2415 |
Inconsistency between unique_ptr and shared_ptr |
missing |
C++17 |
LWG 2422 |
std::numeric_limits<T>::is_modulo description: “most machines” errata |
missing |
C++17 |
LWG 2436 |
Comparators for associative containers should always be CopyConstructible |
missing |
C++17 |
LWG 2724 |
The protected virtual member functions of memory_resource should be private |
filesystem |
C++17 |
LWG 2667 |
path::root_directory() description is confusing |
filesystem |
C++17 |
LWG 2669 |
recursive_directory_iterator effects refers to non-existent functions |
filesystem |
C++17 |
LWG 2670 |
system_complete refers to undefined variable ‘base’ |
filesystem |
C++17 |
LWG 2671 |
Errors in Copy |
filesystem |
C++17 |
LWG 2673 |
status() effects cannot be implemented as specified |
filesystem |
C++17 |
LWG 2674 |
Bidirectional iterator requirement on path::iterator is very expensive |
filesystem |
C++17 |
LWG 2683 |
filesystem::copy() says “no effects” |
filesystem |
C++17 |
LWG 2704 |
recursive_directory_iterator’s members should require ‘*this is dereferenceable’ |
filesystem |
C++17 |
LWG 2706 |
Error reporting for recursive_directory_iterator::pop() is under-specified |
filesystem |
C++17 |
LWG 2707 |
path construction and assignment should have “string_type&&” overloads |
filesystem |
C++17 |
LWG 2711 |
path is convertible from approximately everything under the sun |
filesystem |
C++17 |
LWG 2720 |
permissions function incorrectly specified for symlinks |
filesystem |
C++17 |
LWG 2721 |
remove_all has incorrect post conditions |
filesystem |
C++17 |
LWG 2723 |
Do directory_iterator and recursive_directory_iterator become the end iterator upon error? |
filesystem |
C++17 |
LWG 2725 |
filesystem::exists(const path&, error_code&) error reporting |
filesystem |
C++17 |
LWG 2726 |
[recursive_]directory_iterator::increment(error_code&) is underspecified |
filesystem |
C++17 |
LWG 2728 |
status(p).permissions() and symlink_status(p).permissions() are not specified |
parallel |
C++17 |
LWG 2687 |
{inclusive,exclusive}_scan misspecified |
parallel |
C++17 |
LWG 2689 |
Parallel versions of std::copy and std::move shouldn’t be in order |
parallel |
C++17 |
LWG 2727 |
Parallel algorithms with constexpr specifier |
WCFB02 |
C++14 |
LWG 2140 |
notify_all_at_thread_exit synchronization |
WCFB02 |
C++17 |
LWG 2309 |
mutex::lock() should not throw device_or_resource_busy |
RTM |
New |
LWG 2769 |
Redundant const in the return type of any_cast(const any&) |
RC |
C++14 |
LWG 2252 |
Strong guarantee on vector::push_back() still broken with C++11? |
RC |
New |
LWG 2509 |
[fund.ts.v2] any_cast doesn’t work with rvalue reference targets and cannot move with a value target |
RC |
New |
LWG 2744 |
any’s in_place constructors |
RC |
New |
LWG 2746 |
Inconsistency between requirements for emplace between optional and variant |
RC |
New |
LWG 2754 |
The in_place constructors and emplace functions added by P0032R3 don’t require CopyConstructible |
Preview 5 |
C++14 |
LWG 2350 |
min, max, and minmax should be constexpr |
Preview 5 |
C++17 |
LWG 2192 |
Validity and return type of std::abs(0u) is unclear |
Preview 5 |
C++17 |
LWG 2276 |
Missing requirement on std::promise::set_exception |
Preview 5 |
C++17 |
LWG 2328 |
Rvalue stream extraction should use perfect forwarding |
Preview 5 |
C++17 |
LWG 2369 |
constexpr max(initializer_list) vs max_element |
Preview 5 |
C++17 |
LWG 2485 |
get() should be overloaded for const tuple&& |
Preview 5 |
C++17 |
LWG 2520 |
N4089 broke initializing unique_ptr<T[]> from a nullptr |
Preview 5 |
C++17 |
LWG 2719 |
permissions function should not be noexcept due to narrow contract |
Preview 5 |
New |
LWG 2713 |
More missing allocator-extended constructors for unordered containers |
Preview 5 |
New |
LWG 2756 |
C++ WP optional<T> should ‘forward’ T’s implicit conversions |
Preview 4 |
C++14 |
LWG 2135 |
Unclear requirement for exceptions thrown in condition_variable::wait() |
Preview 4 |
C++14 |
LWG 2203 |
scoped_allocator_adaptor uses wrong argument types for piecewise construction |
Preview 4 |
C++14 |
LWG 2210 |
Missing allocator-extended constructor for allocator-aware containers |
Preview 4 |
C++17 |
LWG 2063 |
Contradictory requirements for string move assignment |
Preview 4 |
C++17 |
LWG 2219 |
INVOKE-ing a pointer to member with a reference_wrapper as the object expression |
Preview 4 |
C++17 |
LWG 2439 |
unique_copy() sometimes can’t fall back to reading its output |
Preview 4 |
C++17 |
LWG 2476 |
scoped_allocator_adaptor is not assignable |
Preview 4 |
C++17 |
LWG 2566 |
Requirements on the first template parameter of container adaptors |
Preview 4 |
C++17 |
LWG 2576 |
istream_iterator and ostream_iterator should use std::addressof |
Preview 4 |
C++17 |
LWG 2577 |
{shared,unique}_lock should use std::addressof |
Preview 4 |
C++17 |
LWG 2579 |
Inconsistency wrt Allocators in basic_string assignment vs. basic_string::assign |
Preview 4 |
C++17 |
LWG 2583 |
There is no way to supply an allocator for basic_string(str, pos) |
Preview 4 |
C++17 |
LWG 2586 |
Wrong value category used in scoped_allocator_adaptor::construct() |
Preview 4 |
C++17 |
LWG 2684 |
priority_queue lacking comparator typedef |
Preview 4 |
C++17 |
LWG 2716 |
Specification of shuffle and sample disallows lvalue URNGs |
Update 3 |
C++14 |
LWG 2064 |
More noexcept issues in basic_string |
Update 3 |
C++17 |
LWG 2296 |
std::addressof should be constexpr |
Update 3 |
C++17 |
LWG 2596 |
vector::data() should use addressof |
Update 3 |
C++17 |
LWG 2688 |
clamp misses preconditions and has extraneous condition on result |
Update 2 |
C++14 |
LWG 2005 |
unordered_map::insert(T&&) protection should apply to map too |
Update 2 |
C++14 |
LWG 2021 |
Further incorrect usages of result_of |
Update 2 |
C++14 |
LWG 2132 |
std::function ambiguity |
Update 2 |
C++14 |
LWG 2196 |
Specification of is_*[copy/move]_[constructible/assignable] unclear for non-referencable types |
Update 2 |
C++17 |
LWG 2101 |
Some transformation types can produce impossible types |
Update 2 |
C++17 |
LWG 2106 |
move_iterator wrapping iterators returning prvalues |
Update 2 |
C++17 |
LWG 2127 |
Move-construction with raw_storage_iterator |
Update 2 |
C++17 |
LWG 2217 |
operator==(sub_match, string) slices on embedded ‘\0’s |
Update 2 |
C++17 |
LWG 2312 |
tuple’s constructor constraints need to be phrased more precisely |
Update 2 |
C++17 |
LWG 2353 |
std::next is over-constrained |
Update 2 |
C++17 |
LWG 2354 |
Unnecessary copying when inserting into maps with braced-init syntax |
Update 2 |
C++17 |
LWG 2367 |
pair and tuple are not correctly implemented for is_constructible with no args |
Up2 opt-in |
C++17 |
LWG 2385 |
function::assign allocator argument doesn’t make sense |
Update 2 |
C++17 |
LWG 2393 |
std::function’s Callable definition is broken |
Update 2 |
C++17 |
LWG 2455 |
Allocator default construction should be allowed to throw |
Update 2 |
C++17 |
LWG 2466 |
allocator_traits::max_size() default behavior is incorrect |
Update 2 |
C++17 |
LWG 2469 |
Wrong specification of Requires clause of operator[] for map and unordered_map |
Update 2 |
C++17 |
LWG 2549 |
Tuple EXPLICIT constructor templates […] will create dangling references |
VS 2015 |
C++14 |
GB 9 |
Remove gets from C++14 |
VS 2015 |
C++14 |
LWG 2009 |
Reporting out-of-bound values on numeric string conversions |
VS 2015 |
C++14 |
LWG 2078 |
Throw specification of async() incomplete |
VS 2015 |
C++14 |
LWG 2094 |
duration conversion overflow shouldn’t participate in overload resolution |
VS 2015 |
C++14 |
LWG 2097 |
packaged_task constructors should be constrained |
VS 2015 |
C++14 |
LWG 2103 |
std::allocator_traits<std::allocator<T>>::propagate_on_container_move_assignment |
VS 2015 |
C++14 |
LWG 2104 |
unique_lock move-assignment should not be noexcept |
VS 2015 |
C++14 |
LWG 2112 |
User-defined classes that cannot be derived from |
VS 2015 |
C++14 |
LWG 2144 |
Missing noexcept specification in type_index |
VS 2015 |
C++14 |
LWG 2145 |
error_category default constructor |
VS 2015 |
C++14 |
LWG 2162 |
allocator_traits::max_size missing noexcept |
VS 2015 |
C++14 |
LWG 2174 |
wstring_convert::converted() should be noexcept |
VS 2015 |
C++14 |
LWG 2176 |
Special members for wstring_convert and wbuffer_convert |
VS 2015 |
C++14 |
LWG 2187 |
vector<bool> is missing emplace and emplace_back member functions |
VS 2015 |
C++14 |
LWG 2193 |
Default constructors for standard library containers are explicit |
VS 2015 |
C++14 |
LWG 2247 |
Type traits and std::nullptr_t |
VS 2015 |
C++14 |
LWG 2268 |
Setting a default argument in the declaration of a member function assign of std::basic_string |
VS 2015 |
C++14 |
LWG 2272 |
quoted should use char_traits::eq for character comparison |
VS 2015 |
C++14 |
LWG 2275 |
Why is forward_as_tuple not constexpr? |
VS 2015 |
C++14 |
LWG 2278 |
User-defined literals for Standard Library types |
VS 2015 |
C++14 |
LWG 2280 |
begin / end for arrays should be constexpr and noexcept |
VS 2015 |
C++14 |
LWG 2285 |
make_reverse_iterator |
VS 2015 |
C++14 |
LWG 2301 |
Why is std::tie not constexpr? |
VS 2015 |
C++14 |
LWG 2306 |
match_results::reference should be value_type&, not const value_type& |
VS 2015 |
C++14 |
LWG 2315 |
weak_ptr should be movable |
VS 2015 |
C++14 |
LWG 2324 |
Insert iterator constructors should use addressof() |
VS 2015 |
C++14 |
LWG 2329 |
regex_match()/regex_search() with match_results should forbid temporary strings |
VS 2015 |
C++14 |
LWG 2332 |
regex_iterator/regex_token_iterator should forbid temporary regexes |
VS 2015 |
C++14 |
LWG 2339 |
Wording issue in nth_element |
VS 2015 |
C++14 |
LWG 2344 |
quoted()’s interaction with padding is unclear |
VS 2015 |
C++14 |
LWG 2346 |
integral_constant’s member functions should be marked noexcept |
VS 2015 |
C++17 |
LWG 2129 |
User specializations of std::initializer_list |
VS 2015 |
C++17 |
LWG 2133 |
Attitude to overloaded comma for iterators |
VS 2015 |
C++17 |
LWG 2212 |
tuple_size for const pair request header |
VS 2015 |
C++17 |
LWG 2234 |
assert() should allow usage in constant expressions |
VS 2015 |
C++17 |
LWG 2365 |
Missing noexcept in shared_ptr::shared_ptr(nullptr_t) |
VS 2015 |
C++17 |
LWG 2399 |
shared_ptr’s constructor from unique_ptr should be constrained |
VS 2015 |
C++17 |
LWG 2400 |
shared_ptr’s get_deleter() should use addressof() |
VS 2015 |
C++17 |
LWG 2401 |
std::function needs more noexcept |
VS 2015 |
C++17 |
LWG 2403 |
stof() should call strtof() and wcstof() |
VS 2015 |
C++17 |
LWG 2407 |
packaged_task(allocator_arg_t, const Allocator&, F&&) should neither be constrained nor explicit |
VS 2015 |
C++17 |
LWG 2420 |
function<void(ArgTypes…)> does not discard the return value of the target object |
VS 2015 |
C++17 |
LWG 2426 |
Issue about compare_exchange |
VS 2015 |
C++17 |
LWG 2433 |
uninitialized_copy()/etc. should tolerate overloaded operator& |
VS 2015 |
C++17 |
LWG 2440 |
seed_seq::size() should be noexcept |
VS 2015 |
C++17 |
LWG 2442 |
call_once() shouldn’t DECAY_COPY() |
VS 2015 |
C++17 |
LWG 2454 |
Add raw_storage_iterator::base() member |
VS 2015 |
C++17 |
LWG 2458 |
N3778 and new library deallocation signatures |
VS 2015 |
C++17 |
LWG 2464 |
try_emplace and insert_or_assign misspecified |
VS 2015 |
C++17 |
LWG 2467 |
is_always_equal has slightly inconsistent default |
VS 2015 |
C++17 |
LWG 2483 |
throw_with_nested() should use is_final |
VS 2015 |
C++17 |
LWG 2484 |
rethrow_if_nested() is doubly unimplementable |
VS 2015 |
C++17 |
LWG 2486 |
mem_fn() should be required to use perfect forwarding |
VS 2015 |
C++17 |
LWG 2487 |
bind() should be const-overloaded, not cv-overloaded |
VS 2015 |
C++17 |
LWG 2488 |
Placeholders should be allowed and encouraged to be constexpr |
VS 2015 |
C++17 |
LWG 2489 |
mem_fn() should be noexcept |
VS 2013 |
C++14 |
LWG 1214 |
Insufficient/inconsistent key immutability requirements for associative containers |
VS 2013 |
C++14 |
LWG 2011 |
Unexpected output required of strings |
VS 2013 |
C++14 |
LWG 2018 |
regex_traits::isctype Returns clause is wrong |
VS 2013 |
C++14 |
LWG 2033 |
Preconditions of reserve, shrink_to_fit, and resize functions |
VS 2013 |
C++14 |
LWG 2039 |
Issues with std::reverse and std::copy_if |
VS 2013 |
C++14 |
LWG 2047 |
Incorrect “mixed” move-assignment semantics of unique_ptr |
VS 2013 |
C++14 |
LWG 2049 |
is_destructible is underspecified |
VS 2013 |
C++14 |
LWG 2050 |
Unordered associative containers do not use allocator_traits to define member types |
VS 2013 |
C++14 |
LWG 2056 |
future_errc enums start with value 0 (invalid value for broken_promise) |
VS 2013 |
C++14 |
LWG 2061 |
make_move_iterator and arrays |
VS 2013 |
C++14 |
LWG 2067 |
packaged_task should have deleted copy c’tor with const parameter |
VS 2013 |
C++14 |
LWG 2074 |
Off by one error in std::reverse_copy |
VS 2013 |
C++14 |
LWG 2083 |
const-qualification on weak_ptr::owner_before |
VS 2013 |
C++14 |
LWG 2087 |
iostream_category() and noexcept |
VS 2013 |
C++14 |
LWG 2096 |
Incorrect constraints of future::get in regard to MoveAssignable |
VS 2013 |
C++14 |
LWG 2128 |
Absence of global functions cbegin/cend |
VS 2013 |
C++14 |
LWG 2138 |
atomic_flag::clear ordering constraints |
VS 2013 |
C++14 |
LWG 2141 |
common_type trait produces reference types |
VS 2013 |
C++14 |
LWG 2143 |
ios_base::xalloc should be thread-safe |
VS 2013 |
C++14 |
LWG 2148 |
Hashing enums should be supported directly by std::hash |
VS 2013 |
C++14 |
LWG 2188 |
Reverse iterator does not fully support targets that overload operator& |
VS 2013 |
C++14 |
LWG 2197 |
Specification of is_[un]signed unclear for non-arithmetic types |
VS 2013 |
C++14 |
LWG 2213 |
Return value of std::regex_replace |
VS 2013 |
C++14 |
LWG 2229 |
Standard code conversion facets underspecified |
VS 2013 |
C++14 |
LWG 2284 |
Inconsistency in allocator_traits::max_size |
VS 2013 |
C++14 |
LWG 2293 |
Wrong facet used by num_put::do_put |
VS 2013 |
C++14 |
LWG 2313 |
tuple_size should always derive from integral_constant |
VS 2013 |
C++14 |
LWG 2317 |
The type property queries should be UnaryTypeTraits returning size_t |
VS 2013 |
C++14 |
LWG 2330 |
regex(“meow”, regex::icase) is technically forbidden but should be permitted |
VS 2013 |
C++14 |
LWG 2341 |
Inconsistency between basic_ostream::seekp(pos) and basic_ostream::seekp(off, dir) |
VS 2013 |
C++14 |
LWG 2359 |
How does regex_constants::nosubs affect basic_regex::mark_count()? |
VS 2013 |
C++14 |
LWG 2360 |
reverse_iterator::operator*() is unimplementable |
VS 2013 |
C++17 |
LWG 2244 |
Issue on basic_istream::seekg |
VS 2013 |
C++17 |
LWG 2273 |
regex_match ambiguity |
VS 2013 |
C++17 |
LWG 2441 |
Exact-width atomic typedefs should be provided |
VS 2013 |
C++17 |
LWG 2473 |
basic_filebuf’s relation to C FILE semantics |
VS 2013 |
C++17 |
LWG 2537 |
Constructors for priority_queue taking allocators should call make_heap |
VS 2013 |
C++17 |
LWG 2560 |
is_constructible underspecified when applied to a function type |
This table is enormous, even after omitting 146 N/A issues. The Library Working Group fixes a lot of bugs in the Standard.
“New” indicates issues which haven’t actually been resolved in C++17 yet. We felt that these issues had to be dealt with before shipping the affected feature, and we expect that our implemented resolution will be accepted.
“RTM” indicates an issue which has been fixed for the official release of VS “15”, but not in time for the Release Candidate build.
“WCFB02” indicates issues that will be fixed in a future, binary-incompatible release of the STL (but not the STL shipping in VS “15”).
“filesystem” indicates issues affecting <filesystem>, which we’ll be analyzing when we overhaul that feature’s implementation.
“parallel” indicates issues affecting the Parallel Algorithms feature, which we haven’t yet implemented.
Note that we’ve implemented all C++14 STL features (result_of SFINAE in VS 2015 Update 2 was the last one) and all C++14 Library Issues. Excluding LWG 2140 (which had to be fixed outside of VS “15” due to bincompat), the last Library Issue was LWG 2252, fixed by a major overhaul of std::vector in VS “15” RC. We’ll publish more details about that in the near future.
Two issues here are notable. LWG 2350 and LWG 2369, implemented in Preview 5, mean that we’ve enabled C++14 constexpr in min/max/minmax(initializer_list) and min_element/max_element/minmax_element(). However, while this is supported by our codegen compilers (C1XX and Clang), this is not yet supported by our Intellisense compiler (EDG). We’re working on fixing this.
Billy Robert O’Neal III – @MalwareMinigun – bion@microsoft.com
Casey Carter – @CoderCasey – cacarter@microsoft.com
Stephan T. Lavavej – @StephanTLavavej – stl@microsoft.com
C++ Core Check code analysis is included with VS “15”
Visual Studio “15” Preview 5 now includes the C++ Core Guidelines Checkers. This means you no longer have to install the C++ Core Check package from NuGet to check your code against rules and profiles in the C++ Core Guidelines. Just configure Code Analysis to include the C++ Core Check extensions.
You can configure Code Analysis in the Solution or Project Property Pages. Either right click on the project or solution or select “Analyze->Configure Code Analysis” from the menu bar.
Find the Code Analysis entry on the bottom of the Property Page and select “Extensions”. Here you’ll find two options: one to enable the Released C++ Core Checks, and one to enable the Experimental Core Checks.
Release checks vs. Experimental checks
What’s the difference between the release checks and the experimental checks? The release checks are more robust. The warnings they find are higher confidence than the experimental checks, and the checker itself runs faster. Right now they include the first set of C++ Core Guidelines checks we released with VS 2015 Update 1 as well as some additional checks from the Guidelines.
The experimental checks include rules that are in development but can still be interesting to run against your code. These include the Lifetime checks we previewed in March 2016 as well as some other checks under development. Note that while most checks will move from “experimental” into “release” you shouldn’t rely on any of the checks in the experimental group. Some of these are prototypes that won’t ever make their way into the release group.
Future of the NuGet-based packages
Remember that if you’re using Visual Studio 2015 you’ll have to still have to install the C++ Core Check package from NuGet. This change is only for Visual Studio “15”, the next major version of Visual Studio. (Note that VS “15” != Visual Studio 2015. Each version of Visual Studio has two names: the internal name is a simple incrementing number, the external name is the year of its release. Visual Studio “15” happens to be in development while Visual Studio 2015 is the current released version but they are different releases. Visual Studio “15” will be rebranded with the year of its release–Visual Studio 2016, Visual Studio 2017, etc.)
The CppCoreCheck packages distributed through NuGet now will remain available for users of VS 2015. But in the future we’ll focus our efforts on the checkers built into Visual Studio. We’ve always required that you use the latest released VS update with the newest CppCore Check because there’s a tight coupling between the C++ compiler and the code analysis tools. Once Visual Studio “15” releases you can continue to use the existing NuGet packages with Visual Studio 2015 but if you want the newest checkers you’ll need to upgrade to Visual Studio “15”.
The tight coupling between the C++ compiler and code analysis tools means that when you bring an existing VS 2015 project to VS “15” you’ll have to move the project to use the newer platform toolset. You can easily do this by bringing up the Project Properties (by right-clicking on the project) and selecting “Platform Toolset” under the “General” category. Once you choose “Visual Studio 2016 (v141)” you should see the settings for Extensions in the Code Analysis section of the project property page.
Send us your feedback!
As always, we welcome your feedback. For problems, let us know via the Report a Problem option, either from the installer or the Visual Studio IDE itself. For suggestions, let us know through UserVoice. And you can always reach us through e-mail at cppcorecheck@microsoft.com.
C++/WinRT Available on GitHub
C++/WinRT is now available on GitHub. This is the future of the Modern C++ project and the first public preview coming officially from Microsoft.
https://github.com/microsoft/cppwinrt
C++/WinRT is a standard C++ language projection for the Windows Runtime implemented solely in header files. It allows you to both author and consume Windows Runtime APIs using any standards-compliant C++ compiler. C++/WinRT is designed to provide C++ developers with first-class access to the modern Windows API.
C++/WinRT, along with libraries like Boost and Range-v3, has been instrumental in helping us find bugs in our efforts to make the Visual C++ conform to the C++ standard. C++/WinRT works with the latest Visual C++ compilers including the toolsets in Visual Studio “15” Preview 5 and Visual Studio 2015 Update 3.
Please give us your feedback as we work on the next set of features.
CppRestSDK 2.9.0 is available on GitHub
We are delighted to announce a new version of CppRestSDK (Casablanca) 2.9.0, this new version available on GitHub introduces new features and fixes issues reported on the 2.8.0 version. The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design. This project aims to help C++ developers connect to and interact with services.
We added
- support for basic authentication on Linux.
- static library support for Windows xp
- a project for compiling as a static lib on Windows
- a websocket_client_config option for ssl verify mode
- host based connection pool map on non windows http_clients
We fixed issues of Linux, OSX and Android versions. Here are the set of changes going into this release:
Linux
-
#143 Work around SSL compression methods memory leak in ASIO.
-
#82 Fixed ambiguous call to begin when using with boost library.
-
#117 Fix header reading on linux listener using HTTPS.
-
#97 Add support for basic authentication.
-
#206 remove warnings-errors for system-headers under linux; honour http_proxy env-variable.
OSX
-
#114 Removed redundant std::move() that was causing errors on Xcode 7.3 gcc.
-
#140 Fix returning std::move causing build failure on osx.
Android
-
#137 Fix android build script for linux, remove libiconv dependency.
-
Use Nuget packages built with Clang 3.8 (VS 2015 Update3) and Android NDK 11rc. Update built scripts for the same.
Windows
-
#150 Add static library for windows xp.
-
#115 Added projects which target v140_xp to resolve Issue#113.
-
#71 Add a project for compiling as a static lib.
WebSockets
-
#102 Added websocket_client_config option for ssl verify mode.
-
#217 Fixed race condition in Casablanca WinRT Websocket client.
http_client
-
#131 Update to include access control allow origin.
-
#156 add host based connection pool map on non windows http_clients.
-
#161 Header parsing assumes whitespace after colon.
-
#146 Fix ambiguous reference to ‘credentials’
Uri
-
#149 Some perf improvements for uri related code.
Json
· #86 Fix obtaining raw string_t pointer from temporary.
· #96 Fix typo hexidecimal/hexadecimal.
-
#116 Fixing latin1 to UTF-16 conversion.
pplx
-
#47 Fixing .then to work with movable-only types.
As always, we trust the community to inform our next steps so, let us know what you need, how to improve Casablanca, by continuing to create an issue or a pull request on https://github.com/Microsoft/cpprestsdk
Building your C++ application with Visual Studio Code
Over the last few months, we have heard a lot of requests with respect to adding capability to Visual Studio Code to allow developers to build their C/C++ application. The task extensibility in Visual Studio Code exists to automate tasks like building, packaging, testing and deploying. This post is going to demonstrate how using task extensibility in Visual Studio Code you can call compilers, build systems and other external tasks through the help of the following sections:
- Installing C/C++ build tools
- Creating a simple Visual Studio Code task
- Calling GCC and Clang directly from Visual Studio Code task
- Calling Makefiles using Visual Studio Code task extensibility
- Calling MSBuild using Visual Studio Code task extensibility
- Calling MSBuild using Visual Studio Code task extensibility
- Calling CMake using Visual Studio Code extensibility
Installing C/C++ build tools
In order to build your C++ code you need to make sure you have C/C++ build tools (compilers, linkers and build systems) installed on your box. If you can already build outside Visual Studio Code you already have these tools setup, so you can move on to the next section.
To obtain your set of C/C++ compilers on Windows you can grab the Visual C++ build tools SKU. By default these tools are installed at ‘C:\Program Files (x86)\Microsoft Visual C++ Build Tools’. You only need to do this if you don’t have Visual studio installed. If you already have Visual Studio installed, you have everything you need already.
If you are on a Linux platform which supports apt-get you can run the following commands to make sure you grab the right set of tools for building your C/C++ code.
sudo apt-get install g++ sudo apt-get install clang
On OS X, the easiest way to install the C++ build tools would be to install Xcode command line tools. You can follow this article on the apple developer forum. I would recommend this instead of installing clang directly as Apple adds special goodies to their version of the clang toolset. Once installed you can run these commands in a terminal window to determine where the compiler and build tools you need were installed.
xcodebuild -find make xcodebuild -find gcc xcodebuild -find g++ xcodebuild -find clang xcodebuild -find clang++
Creating a simple Visual Studio Code task for building C/C++ code
To follow this specific section you can go ahead and download this helloworld C++ source folder. If you run into any issues you can always cheat and download the same C++ source folder with a task pre-configured.
If you are just picking up C++ and want to understand different components involved in performing a simple build you can review this guide.
In Visual Studio Code tasks are defined for a workspace and Visual Studio Code comes pre-installed with a list of common task runners. In the command palette (Ctrl+Shift+P (Win, Linux), ⇧⌘P (Mac)) you can type tasks and look at all the various task related commands.
On executing the ‘Configure Task Runner’ option from the command palette you will see a list of pre-installed tasks as shown below, in the future we will grow the list of task runners for popular build systems but for now go ahead and pick up the others template from this list.
This will create a tasks.json file in your .vscode folder with the following content:
{ // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "0.1.0", "command": "echo", "isShellCommand": true, "args": ["Hello World"], "showOutput": "always" }
Setting it up for Windows
The easiest way to setup Visual Studio Code on Windows for C/C++ building is to create a batch file called ‘build.bat’ with the following commands:
@echo off call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x64 set compilerflags=/Od /Zi /EHsc set linkerflags=/OUT:hello.exe cl.exe %compilerflags% helloworld.cpp /link %linkerflags%
Please note that the location of vcvarsall.bat file which sets up the right environment for building could be different on your machine. Also if you are using the Visual C++ build SKU, you will need to call the following command instead:
call “C:\Program Files (x86)\Microsoft Visual C++ Build Tools\vcbuildtools.bat” x64
Once the build script is ready you can then modify your tasks.json to directly call your batch file on Windows by making the following changes to the automatically generated tasks.json file.
{ // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "0.1.0", "windows": { "command": "build.bat", "isShellCommand": true, "showOutput": "always" }
Initiate a build by bringing up the command palette again and executing the ‘Run Build Task’ command.
This should initiate the build for our C++ application and you should be able to monitor the build progress in the output window.
Now even though this is a Windows specific example you should be able to re-use the same series of steps to call a build script on other platforms as well.
Calling Clang and GCC from Visual Studio Code task for building C/C++ code
Alright let us now see how we can achieve building our C/C++ application without calling an external batch file using some popular toolsets like GCC and Clang directly without a build system in play.
To follow this specific section you can go ahead and download this helloworld C++ source folder. If you run into any issues you can always cheat and download the same C++ source folder with a task pre-configured.
Tasks.json allow you to specify qualifiers like the one below for ‘OS X’. These qualifiers similar will allow you create specific build configurations for your different build targets or as shown in this case for different platforms.
"OS X": { "command": "clang++", "args": [ "-Wall", "helloWorld.cpp", "-v" ], "isShellCommand": true, "showOutput": "always", "problemMatcher": { "owner": "cpp", "fileLocation": [ "relative", "${workspaceRoot}" ], "pattern": { "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", "file": 1, "line": 2, "column": 3, "severity": 4, "message": 5 } }
Another thing to highlight in this snippet is the ‘problemMatcher’ section. Visual Studio Code ships with some of the most common problem matchers out of the box but many compilers and other tools define their own style of errors and warnings. Need not worry you can create your own custom problem matcher as well with Visual Studio Code. This site which helps test out regex online might also come in handy.
The pattern matcher here will work well for Clang and GCC toolsets so just go ahead and use them. The figure below shows them in effect when you initiate the show problems command in Visual Studio Code (Cntrl+Shift+M (Win, Linux), ⇧⌘M (Mac)).
Calling Makefiles using Visual Studio Code task extensibility
Similar to the manner how you configure tasks.json to call the compiler, you can do the same for makefiles. Take a look at the sample tasks.json below, the one new concept in this tasks.json file is the nesting of tasks. Both ‘hello’ and ‘clean’ are tasks in the makefile where as ‘compile w/o makefile’ is a separate task but this example should show you how you can setup tasks.json in cases where there are
multiple build systems at play. You can find the entire sample here.
Note this is an OSX, Linux specific example but to obtain the same behavior on Windows you can replace ‘bash’ with ‘cmd’ and ‘args’ with ‘/C’.
{ // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "0.1.0", "osx": { "command": "bash", "args": ["-c"], "isShellCommand": true, "showOutput": "always", "suppressTaskName": true, "options": { "cwd": "${workspaceRoot}" }, "tasks": [ { "taskName": "hello", "args": [ "make hello" ], "isBuildCommand": true }, { "taskName": "clean", "args": [ "make clean" ] }, { "taskName": "compile w/o makefile", "args": [ "clang++ -Wall -g helloworld.cpp -o hello" ], "echoCommand": true } ] } }
Two more things to mention here is that whichever task you associate the ‘isBuildCommand’ with becomes your default build task in Visual Studio Code. In this case that would be the ‘hello’ task. If you would like to run the other tasks bring up the command palette and choose ‘Run Task’ option.
Then choose the individual task to run e.g. ‘clean’ task. Alternatively, you can also wire the build task as a different key binding. For doing so bring up File -> Preferences -> Keyboard shortcuts and add the following key binding to your task. Bindings currently only exist for build and test tasks but an upcoming fix in the October release will allow bindings for individual tasks as well.
[ { "key": "f7", "command": "workbench.action.tasks.build" } ]
Calling MSBuild using Visual Studio Code task extensibility
MSBuild is already a pre-installed task that Visual Studio Code comes with. Bring up the command palette and choose MSBuild, this will create the following task.json it should be easy then to add your MSBuild solution, project name to the ‘args’ section and get going.
{ // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "0.1.0", "command": "msbuild", "args": [ // Ask msbuild to generate full paths for file names. "/property:GenerateFullPaths=true" ], "taskSelector": "/t:", "showOutput": "silent", "tasks": [ { "taskName": "build", // Show the output window only if unrecognized errors occur. "showOutput": "silent", // Use the standard MS compiler pattern to detect errors, warnings and infos "problemMatcher": "$msCompile" } ] }
Calling CMake using Visual Studio Code extensibility
There are currently two Visual Studio Code extensions in the Visual Studio Code marketplace. The first extension provides the language service support for CMake the latter will allow for building your CMake targets. For a good CMake experience in Visual Studio Code install both extensions.
Once configured you should be able to build specific CMake targets and perform other CMake actions as illustrated in the figure below.
Wrap Up
This post provides some guidance with examples on how to use Visual Studio Code task extensibility to build your C/C++ application. If you would like us to provide more guidance on this or any other aspect for Visual Studio Code by all means do reach out to us by continuing to file issues at our Github page and keep trying out this experience and if you would like to shape the future of this extension please join our Cross-Platform C++ Insiders group, where you can speak with us directly and help make this product the best for your needs.
Recommendations to speed C++ builds in Visual Studio
In this blog, I will discuss features, techniques and tools you can use to reduce build time for C++ projects. The primary focus of this post is to improve developer build time for the Debug Configuration as a part of your Edit/Build/Debug cycle (inner development loop). These recommendations are a result of investigating build issues across several projects.
Developers invoke build frequently while writing and debugging code, so improvements here can have a large impact on productivity. Many of the recommendations focus on this stage, but others will carry over to build lab scenarios, clean builds with optimizations for end-end functional and performance testing and release.
Our recommendations include:
- Use Precompiled Headers
- Use /MP compiler setting
- Use Incremental linking
- Use /debug:fastlink linker setting
- Consider using third party build accelerators
- Sign up for help
Before We Get Started
I will highlight the search feature in project settings. This feature will make it easy for you to locate and modify project settings.
- Bring up the project properties and expand sub groups for the tool you are interested in.
- Select “All options” sub group and search for the setting by name or the command line switch e.g. Multi-processor or /MP as shown in the figure below:
- If you cannot find the setting through search, select “Command Line” sub group and specify the switch in Additional Options
Recommendations
Specific recommendations include:
- DO USE PCH for projects
- DO include commonly used system, runtime and third party headers in PCH
- DO include rarely changing project specific headers in PCH
- DO NOT include headers that change frequently
- DO audit PCH regularly to keep it up to date with product churn
- DO USE /MP
- DO Remove /Gm in favor of /MP
- DO resolve conflict with #import and use /MP
- DO USE linker switch /incremental
- DO USE linker switch /debug:fastlink
- DO consider using a third party build accelerator
Precompiled Header
Precompiled headers (PCH) reduce build time significantly but require effort to set up and maintain for the best results. I have investigated several projects that either didn’t have a PCH or had one that was out of date. Once PCH was added or updated to reflect current state of the project, compile time for individual source files in the project reduced by 4-8x (~4s to <1s).
An ideal PCH is one that includes headers that meet the following criteria
- Headers that don’t change often.
- Headers included across a large number source files in the project.
System (SDK), runtime header and third party library headers generally meet the first requirement and are good candidates to include in PCH. Creating a PCH with just these files can significantly improve build times. In addition, you can include your project specific headers in PCH if they don’t change often.
Wikipedia article on the topic or searching for ‘precompiled headers’ is a good starting point to learn about PCH. In a future blog post I will talk about PCH in more detail and as well as tools to help maintain PCH files.
Recommendation:
- DO USE PCH for projects
- DO include commonly used system, runtime and third party headers in PCH
- DO include rarely changing project specific headers in PCH
- DO NOT include headers that change frequently
- DO audit PCH regularly to keep it up to date with product churn
/MP – Parallelize compilation of source files
Invokes multiple instances of cl.exe to compile project source files in parallel. See documentation for /MP for a detailed discussion of the switch including conflicts with other compiler features. In addition to documentation this blog post has good information about the switch.
Resolving conflicts with other compiler features
- /Gm (enable minimal rebuild): I recommend using /MP over /Gm to reduce build time.
- #import: Documentation for /MP discusses one option to resolve this conflict. Another option is to move all import directives to precompiled header.
- /Yc (create precompiled header): /MP does not help with creating precompiled header so not an issue.
- /EP, /E, /showIncludes: These switches are typically used to diagnose issues hence should not be an issue.
Recommendation:
- DO USE /MP
- DO Remove /Gm in favor of /MP
- DO resolve conflict with #import and use /MP
/incremental – Incremental link
Incremental link enables the linker to significantly speed up link times. With this feature turned on, linker can process just the diffs between two links to generate the image and thus speed up link times by 4-10x in most cases after the first build. In VS2015 this feature was enhanced to handle additional common scenarios that were previously not supported.
Recommendation:
- DO USE linker switch /incremental
/debug:fastlink – Generate partial PDB
The linker spends significant time in collecting and merging debug information into one PDB. With this switch, debug information is distributed across input object and library files. Link time for medium and large projects can speed up by as much as 2x. Following blog posts discuss this feature in detail
Recommendation:
- DO USE linker switch /debug:fastlink
Third party build accelerators
Build accelerators analyze Msbuild projects and create a build plan that optimizes resource usage. They can optionally distribute builds across machines. Following are a couple of build accelerators that you may find beneficial.
- Incredibuild: A link to install VS extension is available under New project/Build accelerators. Visit their website for more information.
- Electric Cloud: Visit their website for download link and more information
In addition to improving build time, these accelerators help you identify build bottlenecks through build visualization and analysis tools.
Recommendation:
- DO consider using a third party build accelerator
Sign up to get help
After you have tried out the recommendations and need further help from the Microsoft C++ team, you can sign up here. Our product team will get in touch with you.
If you run into any problems like crashes, let us know via the Report a Problem option, either from the installer or the Visual Studio IDE itself. You can also email us your query or feedback if you choose to interact with us directly! For new feature suggestions, let us know through User Voice.
Vcpkg updates: Static linking is now available
One month ago, we announced the availability of Vcpkg a command line tool to easily acquire and build open source C++ lib and consume it in Visual Studio 2015. The initial release provided only dynamic link libraries, but we heard your feedback, and we are pleased to announce static linking support with Vcpkg.
To generate static libraries, use one of the triplets: x86-windows-static, or x64-windows-static
For example, to build zlib statically for x86 use:
vcpkg install zlib:x86-windows-static
The library will be installed in the following folder: vcpkg\installed\x86-windows-static
Using static libraries
Updated on 11/4: to clarify /MT usage and provide guidance how to override auto-detection of triplets
We currently deploy a set of built-in triplets that will build static libraries against the static CRT (/MT in Visual Studio): x86-windows-static, x64-windows-static, etc.
In Visual Studio, you can override the auto-detected triplet (which will default to DLLs) using the MSBuild properties “VcpkgTriplet” and “VcpkgEnabled”. For larger solutions, property sheets are a great way to manage these settings
Example:
<PropertyGroup Label="Globals"> .... <VcpkgTriplet>x86-windows-static</VcpkgTriplet> <VcpkgEnabled>true</VcpkgEnabled> </PropertyGroup>
In CMake, you can override the auto-detected DLL triplet using `-DVCPKG_TARGET_TRIPLET=x86-windows-static` along with the normal toolchain argument. For example:
cmake .. -DCMAKE_TOOLCHAIN_FILE=.../vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x86-windows-static
Note again that all libraries in the *-windows-static triplets are linked against the static CRT (/MT or /MTd), so you will need to change your CMAKE_CXX_FLAGS (see http://stackoverflow.com/questions/14172856/cmake-compile-with-mt-instead-of-md).
Community contributions
We really want to say thanks to the community. We started with 20 libraries in the catalog, and the community contributed an additional 60+ more lib, for a total of more than 90 libraries [see the complete list here] The tempo is amazing with almost one new library being added each day: you guys really rock! We collected very good feedback, and many interesting suggestions as well as many requests to add more libraries. Thanks for every contribution and comment, that’s the way we want this project to succeed: by being a real community driven effort.
If you need a specific library, please create an issue identifying the lib you want, don’t hesitate to be precise on the version asked, the source location… To see the list of libraries asked so far, see the issues list tagged with “new port request”. Once the issue is created, the community can jump on your ask and create the right port file. Or if you are already familiar with building the library, please make a Pull Request with your port file and the associated patch file if needed.
We have updated the documentation
We improved the port file creation topics see example #2 “Package a remote project” in example.md and a patch file example to help you create and maintain the port file collection more easily.
With static linking we have now reached an important milestone, we are currently planning the next milestone in our roadmap, and this is the right time to share your suggestions and hope for this project. Create an issue on GitHub [ https://github.com/Microsoft/vcpkg ] and engage the conversation.
See you soon on the GitHub repo, for any question you can contact us at vcpkg@microsoft.com
Developing Linux C++ applications with Azure Docker containers
In recent years, Visual Studio has added new features and experiences to allow developers to develop their C++ applications for non-Windows platforms such as Android, iOS and more recently Linux. One of the challenges that Linux development brings to the table is making sure your native application works across the wide set of Linux distributions available. We have experienced this first-hand when developing the Visual Studio Code C/C++ extension where we needed to test the extension across a wide variations of Linux distributions. We typically build and test our C++ code on different versions of Ubuntu, Debian, Fedora, Arch, openSUSE and more. Furthermore, there are different versions of the standard C library and compilers which bring their own set of issues. To keep costs low for Linux development we made use of Docker containers on Azure.
This blog provides a walkthrough on how to use Azure VMs, Docker containers, and Visual Studio to author your multi-distro Linux C++ application with the help of the following sections:
- Prerequisites
- Docker Containers and Images
- Creating an Azure Docker VM
- Running a Docker container
- Setting up SSH for your container
- Developing your Linux C++ application from Visual Studio
- Using dockerfiles to automate building of images
Prerequisites
Through the course of this walkthrough you will need to setup the following, so let us just go ahead do this upfront.
- An active Azure account. If you don’t have one, you can sign up for a Free Azure Trial.
- Install Azure Command Line Interface which will provide you with a set of open source shell based commands for creating and managing resources in Azure. Use the Windows MSI installer which will setup the right paths in command shell.
- Docker ToolBox which will allow you to quickly install and setup Docker environment for your computer.
- Visual Studio, with C++ and Linux Development extension which ships today as a separate extension on Visual Studio extension gallery.
Docker Containers and Images
A Docker Container is a “stripped-to-basics” version of your operating system. A Docker Image is a read-only snapshot of your software that can be “run” in a Docker Container. Docker containers can allow you to pack a lot more applications into a single physical server than a Virtual Machine can.
Virtual machines run a full copy of the operating system and a virtual copy of all the hardware that operating systems need to run. In contrast, containers only require a stripped to basic version of your operating system, supporting libraries and programs and system resources required to run a specific program.
Combine this with the additional benefit that Docker containers provide for creating a consistent development environment for development, testing and deployment. Docker is here to stay!
Alright with that very short overview on Docker lets go ahead and setup an Azure Docker VM now.
Step 1:Creating an Azure Docker VM
The easiest way to create an Azure VM is by using the cross-platform Azure command line tools. Once installed and connected to your Azure subscription, you can manage many Azure resources right from the command prompt.
Login into your subscription using the ‘azure login’ command. You will go through the following series of steps shown in the picture below.
Once you have logged in successfully to find a suitable image, run the azure vm image list command and provide additional details where you would like your VM to be hosted ‘location’ and the publisher for the VM images. All Ubuntu images on Azure are shipped by the ‘Canonical’ publisher.
azure vm image list info: Executing command vm image list Location: westus Publisher: Canonical
This will print for you a list of Ubuntu images. For this walkthrough, I will pick up the popular ‘Canonical:UbuntuServer:14.04.5-LTS:14.04.201609190’ image. Alternatively you can pick others from the 16.0 series as well.
The Docker Installation documentation provides step-by-step instructions on how to install the Docker Toolbox, which will in turn install Docker Machine, Engine, Compose, Kitematic and a shell for running the Docker CLI. For this tutorial you will install this on your Windows box where you have setup Visual Studio.
Once Docker is installed and running we can go the next step which is to install our Azure Docker Ubuntu VM using the docker-machine Azure driver. You will need to replace the subscription-id with your subscription-id and your vm name e.g. hello-azure-docker-cpp.
docker-machine create --driver azure --azure-subscription-id b5e010e5-3207-4660-b5fa-e6d311457635 --azure-image Canonical:UbuntuServer:14.04.5-LTS:14.04.201609190 hello-azure-docker-cpp
This will run through the following series of command setting up the VM and installing the necessary Docker tools. If you get stuck, you can follow this guide here.
Next, set up your shell for the machine we created by running the following command, where machine name is the name of the machine you created.
docker-machine env <machine-name>
Step 2:Running a Docker container
The easiest way to get started with a Docker container is to make use of an existing container. For this purpose, we use a pre-existing Debian container by executing the following command.
docker run -p 5000:22 -t -i --restart=always debian /bin/bash
This will download the latest image for Debian from Docker and start a new container with it. You should see the following command window as you go through this step. You can replace ‘debian’ with ‘ubuntu’, ‘fedora’ or ‘opensuse’ for creating containers for other distros.
If this step was successful, you should see your Docker running when you execute the ‘docker ps’ command as shown below:
Step 3:Setting up SSH for your container
To build your C++ application on this newly created Linux container using Visual Studio, you need to enable SSH and install necessary build tools (gdb, g++ etc.). Setting up SSH is generally not recommended for Docker containers, but it is required by the Visual Studio C++ Linux development experience today.
Attach to your running container by using the ‘docker attach <container-id>’ command and run the following commands to setup SSH.
apt-get update apt-get install openssh-server apt-get install g++ gdb gdbserver mkdir /var/run/sshd chmod 0755 /var/run/sshd /usr/sbin/sshd
Next, create a user account to use with the SSH connection to the Docker container we just created. We can do this by running the following commands. Replace <user-name> with the username you would like.
useradd -m -d /home/<user-name>/ -s /bin/bash -G sudo <user-name> passwd <user-name>
All right, we are almost there. The last thing we need to do is make sure the port we are using (5000) is allowed by the inbound-security rules by our Docker resource group’s firewall. The easiest way to do this is to use Azure portal, bring up the network security firewall for the VM we created on Azure and traverse to the inbound security rule. For the VM created in this walk-through the resource is shown below:
As a part of the Inbound security rule, Add and Allow an additional custom TCP security rule with the port you chose for your SSH connection as shown in the figure below.
You should now be able to SSH into your Linux container using your favorite SSH client application. The and in the command below will need to be replaced based on your settings.
ssh -p port-name <user-name>@<ip-address>
Step 4: Developing your Linux C++ application from Visual Studio
To setup Visual Studio for Linux C++ development, you can read this walkthrough, which we keep current. This walkthrough covers installation, project setup and other usage tips, but to summarize, you need to do two things:
First, run the following command on your Linux containers which downloads dependencies required to build and debug.
sudo apt-get install g++ gdb gdbserver
Second, download the Visual C++ for Linux development extension or get it from the Extension Manager in Visual Studio. Please note the Linux extension is only supported for Visual Studio 2015 and above.
Once Visual Studio is set up, go ahead and set up connection properties for all your containers in the Connection Manager. The Connection Manager can be launched from Tools->Options as shown in the figure below:
Notice how by using the Docker containers, you can now develop your application on Debian, different versions of Ubuntu, and Redhat simultaneously using one Virtual Machine from within Visual Studio.
Alright with everything else setup, we can finally start building and debugging Linux C++ code on our containers. You can choose from any of the following simple templates from the File->New Project-> C++ -> Cross Platform -> Linux section as shown in the figure below to get started:
For this exercise, choose the simple Console Application template. If you want to start with something more rich you can use this simple tictactoe project.
Next, pick the Linux distro, Docker container you would like to compile and debug this on. You can choose between them by selecting the one that you would like in the Remote settings section:
You can now start debugging (F5) which will copy your sources remotely, build your application and finally allow you to debug your application.
Great! you are now successfully debugging a C++ Linux application running in a container inside an Azure VM.
Step 5: Using Dockerfiles to automate building of images
So far you’ve used very basic Docker commands to create your Docker containers in the previous sections. The real power of Docker comes from not only enabling you to instantiate different versions of Linux distros on one virtual machine in a cheaper, more productive manner, but Docker also provides a way to create a consistent development environment. This is because Docker lets you use a Docker file with a series of commands to set up the environment on the virtual machine.
A Docker file is similar in concept to the recipes and manifests found in infrastructure automation (IA) tools like chef and puppet. You can bring up your favorite text editor and create a file called ‘Dockerfile’ with the following content.
FROM debian RUN apt-get update && apt-get install -y openssh-server RUN mkdir /var/run/sshd RUN echo 'root:screencast' | chpasswd RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config # SSH login fix. Otherwise user is kicked off after login RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd ENV NOTVISIBLE "in users profile" RUN echo "export VISIBLE=now" >> /etc/profile EXPOSE 22 CMD ["/usr/sbin/sshd", "-D"] RUN apt-get install -y openssh-server g++ gdb gdbserver
You can now run the following commands to build your docker container with this docker file and get it running!
"C:\Program Files\Docker\Docker\resources\bin\docker.exe" build -t debiandockercontainer . "C:\Program Files\Docker\Docker\resources\bin\docker.exe" run -d -P --name debiancontainer debiandockercontainer "C:\Program Files\Docker\Docker\resources\bin\docker.exe" port debiancontainer
Running the ‘docker ps’ command will list your newly created container and you can start with Linux C++ development in Visual Studio.
Wrap up
As always, we welcome your feedback and we would love to learn from your experiences as you try this out. This blog is focused on Linux containers, in the future I will also talk about how you can extend your story with Docker containers for your Windows development.
If you run into any problems, following these steps you can email me your query or feedback if you choose to interact directly! Otherwise, we are happy to see your comments and interact with you here through comments. For general Visual Studio product suggestions, you can let us know through User Voice.
Visual C++ docs: the future is… soon!
We on the Visual C++ documentation team are pleased to announce some changes to the API reference content in the following Visual C++ libraries: STL, MFC, ATL, AMP, and ConcRT.
Since the beginning of MSDN online, the Visual C++ libraries have documented each class member, free function, macro, enum, and property on a separate web page. While this model works reasonably well if you know exactly what you are looking for, it doesn’t support easy browsing or searching through multiple class members. We have heard from many developers that it is painful (sometimes literally) to click between multiple pages when exploring or searching for something at the class level.
Therefore we have re-deployed the above-mentioned reference content as follows:
For STL:
Each header will have a top level topic with the same overview that it currently has, with links to subtopics, which will consist of:
· one topic each for all the functions, operators, enums and typedefs in the header
· one topic for each class or struct which includes the complete content for each member.
· one topic for each class or struct
· one topic for each category of macros and functions, according to how these are currently grouped on MSDN.
We strongly believe this change will make it much easier to read and search the documentation. You will be able to use Ctrl-F to search all instances of a term on the page, you can navigate between methods without leaving the page, and you can browse the entire class documentation just by scrolling.
Non-impacts
1. Reference pages for the CRT, and the C/C++ languages are not impacted.
2. No content is being deprecated or removed as a result of this change. We are only changing the way the content is organized.
3. None of your bookmarks will break. The top level header and class topics all retain their current URLs. Links to subtopics such as class members and free functions will automatically redirect to the correct anchor link in the new location.
4. F1 on members, for now, will be slightly less convenient. It will take you to the class page, where you will have to navigate to the member either by Ctrl-F or by clicking the link in the member table. We hope to improve F1 in the coming months to support anchor links.
Why now?
Documentation at Microsoft is changing! Over the next few months, much content that is now on MSDN will migrate to docs.microsoft.com. You can read more about docs.microsoft.com here at Jeff Sandquist’s blog. On the backend, the source content will be stored in markdown format on public GitHub repos where anyone can contribute by making pull requests. Visual C++ has not moved to the new site just yet, but we are taking the first step by converting our source files from XML to markdown. This is the logical time to make the needed changes. By consolidating content, we have the additional advantage of more manageable repo sizes (in terms of the number of individual files). More content in fewer files should make it easier for contributors to find the content they want to modify.
Give Visual C++ a Switch to Standard Conformance
This post was written by Gabriel Dos Reis, Phil Christensen, and Andrew Pardoe
The Visual C++ Team is excited to announce that the compiler in Visual Studio 2017 RC will feature a mode much closer to ISO C++ standards conformance than any time in its history. This represents a major milestone in our journey to full ISO C++ conformance. The mode is available now as an opt-in via the /permissive-
switch but will one day become the default mode for the Visual C++ compiler.
Got a minute? Try Visual C++ conformance mode
The Visual C++ Team is previewing a compiler mode whereby longstanding non-conforming C++ constructs are rejected. This includes fixes to pre-C++11 non-conformance bugs that affect a significant amount of existing code. Examples are as simple as
typedef int default; // error: ‘default’ is a keyword, not permitted here
or as advanced as the following. Consider:
template<typename T> struct B { int f(); }; template<typename T> struct D : B<T> { int g(); }; template<typename T> int D<T>::g() { return f(); // error: should be ‘this->f()’ }
In the definition of D::g
, the symbol f
is from the dependent base class B
but standard C++ does not permit examining dependent base classes when looking for declarations that satisfy the use of f
. That is an error in the source code that Visual C++ has long failed to diagnose. The fix is to prefix the call with this->
. This fix works in both non-conformance and conformance modes.
The issue in this code sample might sound like a “two-phase name lookup” problem, but it is not quite that. In fact, two phase name lookup is the big missing piece from the first iteration of this standard conformance mode. Visual C++ does not support two-phase name lookup in VS 2017 RC but we expect to complete it early next year. When we do, the definition of /permissive-
will change to include two-phase name lookup. This is an important point: /permissive-
is not a completed feature in VS 2017 RC. You will have to keep your codebase clean as we complete our conformance work in Visual C++.
Opting into the conforming mode, /permissive-
, during the series of VS 2017 update is a commitment to keeping your code base clean and to fixing non-conforming constructs we fix conformance issues in Visual C++. If you make your code compile with /permissive-
today you may still have to make changes when VS 2017 releases, and again with updates to VS 2017 because we may have added more bug fixes for non-conforming behaviors.
The good news is this first release contains most of the big issues. With the exception of two-phase name lookup we don’t expect any major changes. See How to fix your code for a complete list of non-conforming constructs implemented under /permissive-
today and how to fix them. We’ll update this list as we complete the changes.
From the Visual Studio IDE
In Visual Studio 2017 RC there is no setting in the project properties page for /permissive-
. You’ll need to enter the switch manually under “Configuration -> C/C++ -> Additional Options”.
When compiling with /permissive-
, the IDE compiler disables non-conforming Visual C++-specific behaviors and interprets your code following the C++ standard. You’ll notice that these language conformance features are now reflected in the areas of IDE such as IntelliSense and browsing features. In this example, setting /permissive-
causes IntelliSense to flag default
as an illegal identifier.
There are currently a few places where the IntelliSense in the IDE will conform better to the C++ standard than the Visual C++ compiler. For example, when relying on two-phase name lookup during overload resolution the compiler will emit an error. IntelliSense, however, will show that the code is conforming and will not give any red squiggles in the editor. You can see that happening in the screenshot below:
Why is that? You may know that Visual C++ uses a separate compiler for IDE productivity features. Since around 2009 we’ve used a compiler front-end from the Edison Design Group (EDG) to drive IntelliSense and many other features. EDG does a fantastic job at emulating other compilers–if you use Clang in Visual Studio (either through Clang/C2 or when targeting Android or iOS) we put EDG into “Clang mode” where it emulates Clang’s bugs and vendor-specific behaviors. Likewise, when using Visual C++, we put EDG into “Visual C++” mode.
While EDG emulates most VC++ features and bugs faithfully, there still might be some gaps due to the implementation being separate or how we integrated their compiler in the IDE. For example, we’ve implemented some features such as ignoring names from dependent base classes, but we haven’t yet implemented others, such as two-phase name lookup (“two-phase overload resolution” on this page) that are both implemented in EDG. Thus EDG shows the “complete” results IntelliSense even though the Visual C++ compiler doesn’t compile the code correctly.
Any differences you see in the IDE and the compiler are temporary. As we complete our conformance work the IDE and the compiler behaviors will match on all code.
Is there any relation to /Za?
The compiler switch /Za
was an effort started decades ago to carve out a strictly portable behavior across several C++ compilers. The effort was stalled and we no longer recommend it for new projects. The switch /Za
does not support certain key Microsoft SDK header files. By contrast /permissive-
offers a useful conformance mode where input C++ code is interpreted according to ISO C++ rules but also allows conforming extensions necessary to compile C++ on targets supported by Visual C++. For example, you can use /permissive-
with C++/CLI. The compiler switch /Za
rejects a few non-conforming constructs; however the compiler switch /permissive-
is our recommendation going forward for conforming code.
The road ahead
We know that conformance changes can be impactful to your code. In order to provide the best experience we’re splitting the development of /permissive-
into three stages: the development stage, the adoption stage, on-by-default.
Development stage
The initial preview of /permissive-
allows you to try out the switch and make most of the changes that will be required in your code. At this stage there will be some inconsistencies in the experience: the feature set under /permissive-
will grow slightly, and editor features like IntelliSense may not match exactly. But all the changes you make to your code in this stage will work with and without /permissive-
.
Adoption stage
The Visual C++ team will continue to add new conformance behavior under the /permissive-
option throughout the Visual Studio 2017 release cycle. But we know that you rely on libraries and that those libraries also need to work with /permissive-
in order for you to opt-in. Our first priority is to ensure that all public headers from our team, and those from Microsoft as a whole, compile cleanly with the /permissive-
option. For example, the standard library headers compile correctly both with /permissive-
and without. We are also working with the community to make changes to existing open source C++ projects (this typically involves removal of Visual C++-specific workarounds.)
On by default
When developers have had time to migrate their code to conform more closely to the C++ standards we will flip the default so that the compiler applies full ISO C++ standard rules when interpreting your source code. This won’t happen immediately–it’s a long-term goal for our conformance work. Until we make this switch—and at least for the entire Visual Studio 2017 cycle–you will have to opt-in to /permissive-. When we do switch it on by default your existing projects won’t change, but VS will make new projects opt-in to conformance.
Call to action
We encourage you to try the new option /permissive-
in your projects. Please add this option to your build settings–either in the IDE or in your build scripts. If your code is already used cross-platform (i.e., it compiles with multiple compilers on many platforms) and does not contain Visual C++ specific workarounds, the chances are that the code will compile just fine with /permissive-
!
If you do use Visual C++ specific, non-conforming constructs in your code, chances are that your code won’t compile the first time with /permissive-
. There’s a list of patterns below of non-conforming C++ code, the typical error message/number you’ll see, and how to fix the code. The good news is that the fixes work both in the conforming mode and in the permissive mode. Therefore, if you try to compile with /permissive-
and you correct issues, the corrected code will be good for the permissive mode too. This enables you to migrate your code to /permissive-
incrementally, rather than making all of the changes at once.
How to fix your code
Here’s a list of behaviors that are affected by the permissive option today. Note that this list is incomplete because the /permissive-
switch is incomplete. As we add new conforming behaviors the potential breaking changes protected by /permissive- will expand. This means even if you fix your code to work with /permissive- today you may still have to make fixes in the future as we make Visual C++ conform better to the standard. Again, these changes will only affect your code if you opt-in by using the /permissive-
switch.
Lookup members in dependent base
template <class T> struct B { void f(); }; template <class T> struct D : public B<T> // B is a dependent base because its type depends on the type of T. { // One possible fix is to uncomment the following line. If this were a type don't forget the 'typename' keyword // using B<T>::f; void g() { f(); // error C3861: 'f': identifier not found // change it to 'this->f();' } }; template <class T> struct C : public B<T> { C() : B<T>() // error C2955: 'B': use of class template requires template argument list // Change to B<T>() to fix {} }; void h() { D<int> d; d.g(); C<int> c; }
Use of qualified names in member declarations
struct A { void A::f() { } // error C4596: illegal qualified name in member declaration // remove redundant 'A::' to fix };
Initializing multiple union members in a member initializer
union U { U() : i(1), j(1) // error C3442: Initializing multiple members of union: 'U::i' and 'U::j' // Remove all but one of the initializations {} int i; int j; };
Hidden friend name lookup rules
// Example 1 struct S { friend void f(S *); }; // Uncomment this declaration to make the hidden friend visible //void f(S *); // this declaration makes the hidden friend visible using type = void (*)(S *); type p = &f; //error C2065: 'f': undeclared identifier /*--------------------------------------------------------*/ // Example 2 struct S { friend void f(S *); }; void g() { // using nullptr instead of S prevents argument dependent lookup in S f(nullptr); // error C3861: 'f': identifier not found S *p = nullptr; f(p); // hidden friend can be found via argument-dependent lookup. }
Using scoped enums in array bounds
enum class Color { Red, Green, Blue }; int data[Color::Blue];// error C3411: 'Color' is not valid as the size of an array as it is not an integer type // Cast to type size_t or int
Using ‘default’ as an identifier in native code
void func(int default); // Error C2321: 'default' is a keyword, and cannot be used in this context
‘for each’ in native code
void func() { int array[] = {1, 2, 30, 40}; for each( int i in array) // error C4496: nonstandard extension 'for each' used: replace with ranged-for statement // for( int i: array) { // ... } }
Defaulting conformance switches
The compiler switches /Zc:strictStrings
and /Zc:rvalueCast
are currently off by default, allowing non-conforming behavior. The switch /permissive-
turns them on by default. You can pass in the /Zc
flags after /permissive-
to override this behavior if needed.
See these MSDN pages for more information:
/Zc:strictStrings
https://msdn.microsoft.com/en-us/library/dn449508.aspx/Zc:rvalueCast
https://msdn.microsoft.com/en-us/library/dn449507.aspx
ATL attributes
We started to deprecate attributed ATL support in VS 2008. The /permissive-
switch removes support for attributed ATL.
// Example 1 [uuid("594382D9-44B0-461A-8DE3-E06A3E73C5EB")] class A {};
// Fix for example 1 class __declspec(uuid("594382D9-44B0-461A-8DE3-E06A3E73C5EB")) B {};
// Example 2 [emitidl]; [module(name="Foo")]; [object, local, uuid("9e66a290-4365-11d2-a997-00c04fa37ddb")] __interface ICustom { HRESULT Custom([in] long l, [out, retval] long *pLong); [local] HRESULT CustomLocal([in] long l, [out, retval] long *pLong); }; [coclass, appobject, uuid("9e66a294-4365-11d2-a997-00c04fa37ddb")] class CFoo : public ICustom {};
// Fix for example 2 // First, create the *.idl file. The vc140.idl generated file can be used to automatically obtain *.idl file for the interfaces with annotation. // Second, add a midl step to your build system to make sure that the C++ interface definitions are outputted. // Lastly, adjust your existing code to use ATL directly as shown in atl implementation section -- IDL FILE -- import "docobj.idl"; [object, local, uuid(9e66a290-4365-11d2-a997-00c04fa37ddb)] interface ICustom : IUnknown { HRESULT Custom([in] long l, [out,retval] long *pLong); [local] HRESULT CustomLocal([in] long l, [out,retval] long *pLong); }; [ version(1.0), uuid(29079a2c-5f3f-3325-99a1-3ec9c40988bb) ] library Foo { importlib("stdole2.tlb"); importlib("olepro32.dll"); [version(1.0), appobject, uuid(9e66a294-4365-11d2-a997-00c04fa37ddb)] coclass CFoo { interface ICustom; }; } -- ATL IMPLEMENTATION-- #include <idl.header.h> #include <atlbase.h> class ATL_NO_VTABLE CFooImpl : public ICustom, public ATL::CComObjectRootEx<CComMultiThreadModel> { public: BEGIN_COM_MAP(CFooImpl) COM_INTERFACE_ENTRY(ICustom) END_COM_MAP() };
Changes not present in VS 2017 RC
Here are some changes to /permissive-
that we expect to enable in future releases and updates of VS 2017. This list may not be complete.
- Two-phase name lookup
- Error when binding a non-const reference to a temporary
- Not treating copy init as direct init
- Not allowing multiple user-defined conversions in initialization.
- Alternative tokens for logical operators (‘and’, ‘or’, etc…)
In closing
As always, we welcome your feedback. Please give us feedback about the /permissive-
feature in the comments below or through e-mail at visualcpp@microsoft.com.
If you encounter other problems with Visual C++ in VS 2017 RC please let us know via the Report a Problem option, either from the installer or the Visual Studio IDE itself. For suggestions, let us know through UserVoice. Thank you!