Introduction
Visual Studio 2013 Preview (internally called VS12) and .NET Framework 4.5.1 have been made available in June. Though released sooner than expected, it provides new features and improvements over Visual Studio 2012. In this article, I will discuss some of the changes for native development. A more rigorous list of features is available in MSDN. Visual Studio 2013 can be downloaded from here.
C++
There are new C++11 and even C++14 compiler and library features now supported (some of them were available in the November 2012 CTP for Visual Studio 2012). These include:
- compiler support for:
- default template arguments for function templates
- delegating constructors
- explicit conversion operators
- initializer lists and uniform initialization
- raw string literals
- variadic templates
rvalue
/lvalue
Reference Casts
- library support for:
- C++11 explicit conversion operators, initializer list, scoped
enum
s and variadic templates - C++14 features:
- Transparent operator functions
make_unique
- non-member functions
cbegin()
/cend()
, rbegin()
/rend()
, crbegin()
/crend()
In the following paragraphs, I will walk through some of these features, but not all and not in detail, since they have been discussed so many times and you can find enough additional references for all of them.
Delegating Constructors
In C++11, it is possible for a constructor of a class to call in its initialization list another constructor of the same class. Before, it was only possible to call constructors from a base class.
#include <string>
#include <sstream>
int to_int(std::string const & s)
{
std::stringstream sstr(s);
int val;
sstr >> val;
return val;
}
class foo
{
int value;
public:
foo(std::string const & s) : foo(to_int(s)) {}
foo(int a) : value(a) {}
};
If you compile this with Visual Studio 2012, the following error is issued.
error C2614: 'foo' : illegal member initialization: 'foo' is not a base or member
Explicit Conversion Operators
In C++, it is possible to prevent constructors with a single argument to be used as implicit type conversion operators by marking them with the explicit
keyword. In C++11, the same keyword can be used on conversion operators to prevent them from being used in implicit conversions.
In the following example, structure foo
has a conversion operator to int
that enables implicit conversion.
struct foo
{
operator int() { return 42; }
};
foo f;
int i = f;
When we add the explicit keyword, the implicit conversion is no longer possible.
struct foo
{
explicit operator int() { return 42; }
};
foo f;
int i = f;
The assignment now triggers an error:
error C2440: 'initializing' : cannot convert from 'foo' to 'int' No user-defined-conversion
operator available that can perform this conversion, or the operator cannot be called
and requires an explicit cast in order to work:
int i = static_cast<int>(f);
Initializer List and Uniform Initialization
C++ used to allow initializing arrays and structs with an initializer list like this:
int arr [] = { 1, 2, 3, 4, 5 };
However, that was not possible with classes. The following code didn't work:
std::vector<int> v = { 1, 2, 3, 4, 5 };
C++11 introduced the std::initializer_list
, that is a template class living in the header with the same name, bound to an initializer list. This template class can be used as parameter to functions including constructors. A constructor that takes an initializer_list
has precedence over other constructors. In Visual Studio 2013, all relevant STL types have been updated with constructors that take an initializer_list
. That makes the above statement perfectly legal. It is also possible to use the initializer_list
with any function, not just constructors.
int sum(std::initializer_list<int> list)
{
int s = 0;
for (auto const & i : list)
s += i;
return s;
}
auto s = sum({1, 1, 2, 3, 5, 8});
The uniform initialization takes a step further, building on the syntax of initializer list and provides a uniform way for initializing objects of any type (arrays, classes, PODs, etc.). Consider the following code:
class foo
{
int x;
public:
foo() : x(42) {}
foo(int v) : x(v) {}
};
int i [] = { 42 };
foo f1(42);
foo f2;
There are several ways to initialize objects:
- with
{}
for initializer list - with
()
for calling constructors - with-out
()
for calling default constructor
In C++11, it is possible to use the initializer list syntax in all these possible cases. The above sample re-rewritten with uniform initialization looks like this:
int i [] { 42 };
foo f1 { 42 };
foo f2 {};
Raw String Literals
Some special characters (quotes, backslash) required escaping when using them in string literals. In C++11, it is possible to declare "raw" string literals, where the compiler automatically escapes these characters. These raw string literals must be prefixed with R"(
and suffixed with )"
.
auto path = R"(c:\windows)";
auto quotedstring = R"(here are "quotes")";
auto multi = R"(this is the first line
and here comes the second)";
What if you want a string to contain "( or ")? Then you can use a different delimiter (up to 16 characters) between "(
and ")
. For instance, you can use a start, such as "*(
and )*"
.
std::cout << R"*("(sample)")*" << std::endl;
make_unique
std::make_unique constructs an object of a type (including arrays) and wraps it in a std::unique_ptr
object.
auto p = std::make_unique<int>(42);
Transparent Operator Functions
Let's look at the following sample:
int arr [] = {1,2,3,4,5};
std::sort(std::begin(arr), std::end(arr), std::greater<int>());
The intent here is to sort the array using the library std::greater
function. But it requires the type of the elements, which is a bit too verbose (besides, there are different issues that can arise).
So "transparent" operator functions solve this by removing the requirement to specify the type. Transparent means they are both perfect forwarding and perfect returning.
std::sort(std::begin(arr), std::end(arr), std::greater<>());
std::map<int, std::string, std::greater<>> m;
These functors are declared with auto
and decltype
and non-homogenous signatures so they can be used in operations (comparisons or arithmetic) with different types (comparing apples and pears or dividing meters and seconds). Here is, for instance, how std::greater
is defined:
template <> struct greater<void> {
template <class T, class U> auto operator()(T&& t, U&& u) const
-> decltype(std::forward<T>(t) > std::forward<U>(u))
{ return std::forward<T>(t) > std::forward<U>(u); }
};
Additional Readings
C99 Libraries
A good news for C developers is the support for C99 library functions Microsoft has put into this release. Missing declarations and implementations have been added to existing headers and new (unsupported until now) headers have been added. Most of the changes are already in the preview release, but new things will be added into the RTM. A detailed explanation of what's been added and where it is available is in this blog post.
MFC
Of the few documented changes to MFC so far, the most important is the deprecation of the multi-byte character set (MBCS) support. The MBCS version of the library is no longer deployed together with Visual Studio, but is still available as a separate download (you can get it from here). The goal is to completely remove the support for MBCS in the future and only support Unicode. Note that the option to use the Multi-byte character set in the project properties is still available with Visual Studio and if you select this one (or have existing projects using this character set), you get an MSBuild error and are instructed to download it separately and install manually. You can find more details about this change here.
There are also bug-fixes, two of them for problems with CDatabase
for which I blogged workarounds (first bug and second bug).
ATL
The dynamic link library for ATL has been removed and the library is now provided as headers and a static library only. Because the ATL code is no longer character-set dependent and has no specifics to debug/release configurations, there is only one version of the static library (atls.lib). With the removal of the ATL DLL, the ATL/MFC Trace Tool (that used to be available from the Tools menu) was also removed. The ATLTRACE
macros have been also re-implemented to simply rely on CRT debug reporting functions (such as _CrtDbgReportW
).
C++ REST SDK
Visual Studio 2013 deploys with version 1.0 of the C++ REST SDK (a new version 1.1.0 has been released since the preview of Visual Studio 2013). This SDK, formally known as Casablanca project, is also available on Codeplex. It provides a modern C++ API for cloud-based client-server communication. It is cross-platform working both on Windows (minimum required is Vista) and Linux.
The following example queries Google for a specific term (using Google's REST API). The response is a json value that is parsed for displaying the (unformatted) title and URL of each result.
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
#include <cpprest/json.h>
#include <iostream>
using namespace utility;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace concurrency::streams;
using namespace std;
void search_and_print(wstring const & searchTerm)
{
http_client client(U("https://ajax.googleapis.com/ajax/services/search/web"));
auto query = uri_builder()
.append_query(L"q", searchTerm)
.append_query(L"v", L"1.0")
.append_query(L"rsz", L"4")
.to_string();
client
.request(methods::GET, query)
.then([](http_response response) -> pplx::task<json::value>
{
if(response.status_code() == status_codes::OK)
{
return response.extract_json();
}
return pplx::task_from_result(json::value());
})
.then([](pplx::task<json::value> previousTask)
{
try
{
json::value const & v = previousTask.get();
if(!v.is_null())
{
auto response = v[L"responseData"];
auto results = response[L"results"];
for(auto const & p : results)
{
auto o = p.second;
auto url = o[L"url"];
auto title = o[L"titleNoFormatting"];
wcout << title.as_string() << endl << url.as_string() << endl << endl;
}
}
}
catch (http_exception const & e)
{
wcout << e.what() << endl;
}
})
.wait();
}
If this method is called with L"codeproject"
, the following results are displayed:
CodeProject - For those who code
http:
C# - CodeProject
http:
The Code Project - Wikipedia, the free encyclopedia
http:
Codeproject.net: The Leading Source Code Site on the Net
http:
Additional Resources
Vector Calling Convention
A new calling convention was introduced for native x86/x64 targets (but does not apply to mixed-mode /clr
targets). It's called vector calling convention and is specified with the keyword __vectorcall
. It is also possible to compile as __vectorcall
(unless explicitly specified otherwise) all the function in a module by using the compiler's /Gv
switch. The vector calling convention enables utilizing the vector registers for passing vector type arguments (SIMD data types - __m64
, __m128
, __m256
, and HVA/HFA data types). Details about this new calling convention are available in this blog post.
Debugger
Visualizers (The natvis Framework)
Visual Studio 2012 has shipped with a new framework called natvis for building visualizations for native types through natvis files. These are XML files that are loaded by Visual Studio each time the debugger starts (thus any changes are picked up without restarting Visual Studio). The new framework replaced the autoexp.dat file and provided better diagnostics, versioning and multiple files support. Documentation for writing debugger type visualizers for C++ using natvis files can be found here.
Visual Studio 2013 brings several improvements to this framework, including:
- multiple object views (ability to define more than just one view for a type and access it through an appropriate format specifier)
- a specifier for skipping memory addresses
- propagation of format specifiers on visualized objects (for instance, using '
x
' on a vector of integers propagates to its elements and displays them in hexadecimal base) - using the final implementation name of a class inside a display string
- support for circular linked lists
The new changes are documented in this blog post Using Visual Studio 2013 to write maintainable native visualizations (natvis).
Just my Code for C++
It is now possible to instruct the debugger to collapse consecutive frames of non-user code into an annotated frame labeled [External Call] in all windows where call stacks are shown (the Call stack window, the Threads window, the Parallel Stacks window). This feature was previously available only for .NET projects, but was now enabled for C++ as well. The feature is enabled by default and can be toggled on and off using the "Show external code" command in the context menu. It is also possible to completely turn it off from Tools > Options > Debugging > General.
Non-user code is defined in .natjmc files, located in the same place with the native visualizer files. User code is defined at function, file and module level. Adding new files or modifying the existing ones will define what is considered non-user code.
However, there is an exception for not displaying non-user code: when the application stops in non-user code, the external code at the top of the call stack will be shown.
To learn more about this feature, read Just My Code for C++ in VS 2013.
Debugging Async Code
Additional enhancements for the Call Stack window and the Tasks window (formerly called Parallel Tasks) have been added for debugging asynchronous code. These are available for different languages, including C++. Debugging tasks used to be a bit difficult. When an exception occurred, it was impossible to tell from which execution path it was triggered. The Call Stack window now shows the frame that existed on the class stack when the task was created. This frame (or frames) are displayed below the actual call stack under an annotated frame called [Async Call]
. In addition, the Tasks window has additional fields for the task start time and duration (how long it's been scheduled). However, these features in the Tasks window are only available for C++ Store applications.
Additional Readings
JavaScript/Native Interop Debugging
For Windows Store applications built with JavaScript and C++ debugging, both code types were not possible from the same instance of Visual Studio. In Visual Studio 2012, one had to start two instances and attach two different debug engines to the same process. Visual Studio 2013 features a "Native with Script" debugger that provides full native debugging experience complemented with a limited JavaScript debugging support. For full script debugging, you still need to use the "Script only" debugging. For more information, read JavaScript/Native Interop Debugging in Visual Studio 2013.
IDE Changes
There are various improvements and also new features for IDE and productivity tools. Several of them that I find more important (and are more visible) are listed below. For others, see this article. You can also read this blog post about C++ IDE Performance Improvement in Visual Studio 2013.
Code Formatting for C++
New features are available for C++ code formatting, such as indentation, new-line placement of braces and keywords, spacing and line wrapping. Notice that automatic indentation when you type a semicolon (';'), close a bracket ('}') or paste code is enabled by default. You can change the code formatting settings from Tools > Options > Text editor > C/C++ > Formatting.
Brace Completion
The IDE automatically completes for C++ the closing character that corresponds to {
, [
, (
, '
and "
.
Auto Completion Features
Many of us have struggled at least once with lots of errors because we forgot to add a semicolon after declaring a type. Visual Studio 2013 automatically adds a semicolon after declaring a class
, struct
, enum
or union
. In addition, it automatically closes parenthesis for raw string literals (R"()"
) and adds the closing */
for multi-line comments (when you type /*
).
Toggle Header/Code Files
The new command to toggle between header and source file is available from the context menu for the code editor and is called "Toggle Header / Code file". The default shortcut for the command is Ctrl + K, Ctrl + O
.
Conclusions
Visual Studio 2013 ships with new features and improvements that will help native developers: new support for C++11 and even C++14 compiler and libraries, increased support for C99 libraries, bundled C++ REST SDK, debugger improvements and new IDE features. On the other hand, there is little change to MFC (other than bug fixes and deprecated MBCS version of the libraries) and a different distribution of the ATL library (only headers and static library). The official list for what's new in Visual C++ in Visual Studio 2013 is available here.
History
- 6th August, 2013: Initial version