Visual Studio 2013
Beta was made available at the end of February.
Ignoring the commonly disliked chrome theme, the
new version of Visual
Studio provides lots of improvements,
both for managed and native development. In this
article I will enumerate and discuss some of the
new or improved features for native development
(but not all). These include improved or new
features in the C++11 language support, the
compiler and linker, the
VC++ libraries and the IDE. A complete
list of these features is available in MSDN.
Visual Studio 2013
beta can be download from here.
No Windows XP Support
Before discussing what's new I must stress a
very important point:
Visual Studio 2013 does not support
Windows XP and Windows Server 2003 anymore.
Native applications built with
Visual Studio 2013
will no longer run on WinXP/Server2003 because
the VC++ libraries
(CRT and MFC) use
system APIs that are only available starting
with Vista. The minimum supported operating
systems are Windows Server 2008 SP2 and Windows
Vista. An item
on Microsoft Connect targets
this problem.
Mike Ryan has written a blog post about getting
your statically linked
Visual Studio 2013 native application run
on Windows XP, by wrapping the required missing
APIs and making an assembly language forwarding
directive that calls them. His tutorial is
available here.
C++11 Support
Visual Studio 2013
extends the C++ compiler's support for C++11,
but not everything is yet implemented. However,
they have promised to deliver updated support to
core features after the release of
Visual Studio 2013,
probably in the form of a feature pack. This blog
post from the VC++
Team contains
a table with the support for C++11 features in
VS10 and Visual Studio
2013. The new features in
Visual Studio 2013
include:
-
Forward declared enums and
full support for strongly typed enum
-
Standard-layout and trivial
types
-
Range-based for loops
-
Override and final
-
Concurrency features:
reworded sequence points, atomics, strong
compare and exchange, bidirectional fences
and data-dependency ordering
Strongly typed enums
Regular C++ enumerations export their
enumerators to the surrounding scope. This has
two drawbacks. First, it can lead to name
clashes, if two enumerators in different enums
declared in the same scope have the same name;
second, it's not possible to use an enumerator
with a fully qualified name, including the enum
name. These issues have been addressed in the
new standard which provides a new kind of enums,
introduced with "enum class" and called
strongly-typed enums. They no longer export
their enumerators to the surrounding scope, can
have user specified underlying type of an
integral type (also added for tranditional enums)
and do not convert implicitly to int.
Collapse | Copy
Code
enum class Options {None, One, All};
Options o = Options::All;
Forward declaration of enums allows declaring
enums before they are defined.
Collapse | Copy
Code
enum class Options;
void make_selection(Options* op);
enum class Options {None, One, All};
An article on strongly typed enums can be found here.
Range-based for loops
Writing (for) loops over a range of values
didn't use to be very friendly in C++. All major
languages used to have a way to make this
simpler, but not C++. C++11 introduces
range-based for loops that have a simple syntax
for iterating arrays or containers. It looks
like this:
Collapse | Copy
Code
int arr[] = {1,2,3,4,5};
for(int i : arr)
cout << i << " ";
You can even substitute the type and use the
auto keyword, which is especially helpful when
you work with STL containers (and you might have
something like map<int, vector<string>>).
Collapse | Copy
Code
for(auto i : arr)
cout << i << " ";
In this examples the variable 'i' is read-only.
You cannot change its value. If you want to
change the content you can use a reference.
Collapse | Copy
Code
for(auto &i : arr)
i *= i;
The new range-based for loops works with arrays,
strings and STL containers, but also with any
user-defined data structure provided that your
iterator:
-
has a begin() and end()
method operating on your custom data
structure
-
has an operator*, operator !=
and operator++ (the prefix version)
An example on how to write such an iterator can
be found in this
article.
Override and final
C++ didn't use to have a method to specify that
a virtual method in a derived class overrides a
method from the base class. In fact the virtual
keyword is optional on the derived class, which
makes this even more confusing. It is possible
to make mistakes when writing virtual methods.
Let's take for instance this example:
Collapse | Copy
Code
class B
{
public:
virtual void f(int) {cout << "B::f" << endl;}
};
class D : public B
{
public:
virtual void f(float) {cout << "D::f" << endl;}
};
The f() method in class D does not override the
method with the same name in B, because the
argument is of another type. The following
example is also wrong, because B::f is const,
and D::f is not, therefore it's not an override.
Collapse | Copy
Code
class B
{
public:
virtual void f(int) const {cout << "B::f " << endl;}
};
class D : public B
{
public:
virtual void f(int) {cout << "D::f" << endl;}
};
C++11 provides the possibility to specify that a
method is indented to override a base virtual
method. This is achieved by marking a method
with 'override'. This is not a keyword, but a
special identifier, and it can be used elsewhere
as an identifier.
Collapse | Copy
Code
class B
{
public:
virtual void f(int) {cout << "B::f" << endl;}
};
class D : public B
{
public:
virtual void f(float) override {cout << "D::f" << endl;}
};
The code above generates the following compiler
error:
error C3668: 'D::f' : method
with override specifier 'override' did not
override any base class methods
On the other hand it is possible that you do not
want a method to be further overridden in the
hierarchy. The special identifier 'final' (not a
keyword) can be used to mark a function as such.
The following example generates an error.
Collapse | Copy
Code
class B
{
public:
virtual void f(int) final {cout << "B::f" << endl;}
};
class D : public B
{
public:
virtual void f(int) override {cout << "D::f" << endl;}
};
error C3248: 'B::f': function
declared as 'final' cannot be overridden by
'D::f'
Bjarne Stroustrup discusses more about override and final on
his C++11 FAQ page.
C++ Compiler enhancements: auto-vectorizor
and auto-parallelizer
So far the C++ compiler only used the scaler
unit from the CPU. However, nowadays, all CPUs
have a vector unit too (see SSE
on Wikipedia). These contain vector
registers that can perform operations on vectors
(a sequence of numbers) in a single instruction.
That means if you have a loop where data doesn't
carry dependencies (like a loop that performs a
summation) it could be actually executed with
the vector instructions (of course given some
constrains are met), making the execution time
be several times smaller. The C++ compiler in
Visual Studio 2013
has been enhanced to take advantage of the SIMD
instructions and auto-vectorize the loops it
finds safe. This is enabled by default and
requires no changes to your code. Given the
particularities of your program, it can provide
a significant implicit boost.
Besides SSE support, nowadays most CPUs are also
multi-core, which means multiple vector units.
Therefore in addition to the auto-vectorization,
the Visual Studio 2013
C++ compiler can also do an
auto-parallelization, spreading the computation
on multiple cores. The auto-parallelizer is very
conservative and in the current version will
find few cases where the loops can be
auto-parallelized. However, developers can
instruct the compiler to auto-parallelize a loop
by using pragma
loop(hint_parallel(N)). The auto-parallelizer
is not enabled by default on
Visual Studio 2013.
You have to go to your project's properties,
C/C++ > Code Generation and set "Enable Parallel
Code Generation" to "Yes", or use /Qpar if you
build from a command line.
Jim Radigan and Jim Hogg provide insights into
the auto-vectorizor and the auto-parallelizer in
this channel9
interview.
IDE enhancements
C++/CLI IntelliSense
In VS2010 the VC++
team has re-designed the IntelliSense, but
VS2010 shipped without any IntelliSense support
for C++/CLI projects (this VC++
Team blog post explains
why). This has been a major complain and the
good news is that Visual
Studio 2013 comes with IntelliSense
support for C++/CLI. That means features like
Quick Info, Parameter Help, List Members and
Auto Completion do work properly with C++/CLI.
C++ Code Snippets
Code snippets are small blocks of reusable code
that you can insert in your code (such as a
switch or a try-catch block). They have been
available for a while, but not for C++.
Visual Studio 2013
now provides C++ code snippets for switch,
if-else, for loop and other constructs. In
addition, developers can define their own
snippets. This article by
Ovidiu Cucu shows how to do that.
Semantic Colorization
I've been always annoyed by the IDE's inability
to colorize C++ code. I was nicely surprised to
see Visual Studio 2013
has finally done something about it. The new IDE
is able to colorize by default types, enums,
macros and other C++ tokens. More about that here.
Parallel Libraries
Microsoft delivered with Visual Studio 2010 two
C++ libraries for native parallel programming,
one called Parallel Patterns Library (or simply
PPL) used for writing tucancode.net parallelism, and a
second one called Asynchronous Agents Library
used for expressing dataflows and pipelining
tucancode.nets using an actor-based programming model and
message passing. In Visual
Studio 2013 these libraries were extended
to provide better performance, more control and
richer support for the most used parallel
patterns.
The PPL library becomes even more relevant with
Windows 8 and WinRT that offers a new
programming model in which all blocking
operations are asynchronous. PPL makes it easier
for developers to write C++ async code (though
not as easy as in C#), where continuations, a
new feature to the library, plays a key role.
This Asynchronous
Programming in C++ Using PPL article
by Artur Laksberg addresses this topic.
Visual Studio 2013
introduces a new library (announced last summer)
called C++ Accelerated Massive Parallelism (or
simply C++ AMP). This is a native library built
on top of DirectX that allows developers to
write parallel code that runs on heterogeneous
hardware. It aims to make GPU programming easy
for C++ developers. It provides multidimensional
arrays, indexing, memory transfer, tiling, and a
mathematical function library, while language
extensions and compiler restrictions can be used
to control how data moves between the CPU and
GPU. A C++ AMP "Hello world" application can be
found here.
Lots of information and examples can be found on
the blog of
the team that implemented these libraries.
Little MFC
Updates
Visual Studio 2013
doesn't bring any updates to
MFC, except mainly
for a series of bug fixes (including paint/draw
issues or memory leaks) as explained by Pat
Brenner in this blog
post. The only significant change was
reducing the size of statically-linked
MFC applications
that use "MFC
controls". These are the controls that are part
of the feature pack delivered to
MFC in Visual
Studio 2008 and that are prefixed with "MFC"
(such as CMFCButton,
CMFCListCtrl, CMFCToolbar,
CMFCMenuBar, etc.).
In Visual Studio 2010, statically-linked
MFC applications
that use such controls had a dramatic increase
in size. This was fixed for
Visual Studio 2013,
though changes could not be propagated back to
Visual Studio 2010 because it would have broken
existing code. The solution is to define _AFX_NO_MFC_CONTROLS_IN_DIALOGS
in your application if you do not use such
controls. In this case, your application will be
linked with a new, smaller version of the
library that has the same methods, but different
implementation. If at any point you need to add
MFC controls, you
just remove that macro without any other code
changes. Of course, in this case, the
application would be linked to the regular
library implementation and the size would
increase. This blog
post provides
the details of the problem and the solution.
The lack of investment in
MFC is not something unexpected, given
the company's push for Windows 8, WinRT and
Metro style-applications. Unfortunately, this
will probably be the case for all future
releases. I believe MFC
will no longer benefit from any enhancements
other than bug fixes and maybe some header
updates once in a while.
Windows 8
Windows 8 is the new flag ship of the company
and Visual Studio 2013
provides great support for building C++
applications for the new Windows runtime, called
WinRT. (This is also the reason why there are no
important updates to MFC.)
WinRT is still a native runtime. The
applications built for WinRT are called
Metro-style applications. The great part about
it is that the same API is exposed to C++, C#/VB.NET
and JavaScript.
Microsoft has built an extension to C++, called
C++ Component eXtensions, or simply C++/CX. It
is the language used to author native components
or applications for WinRT. It has a very similar
syntax to C++/CLI, though there are some
differences, and unlike the C++/CLI which
targets the CLR, C++/CX targets WinRT and native
code. For more information on this topic read
Nish Sivakumar's Visual
C++ and WinRT/Metro - Some fundamentals.
In Visual Studio 2013
it is possible to:
-
build Metro-style
applications in C++ using the new native
XAML framework or DirectX; it is actually
possible to use both of them in the same
application, the two operate efficiently.
-
build WinRT components for
Metro-style apps written with C++, HTML5/JabaScript
or .NET.
When you install Visual
Studio 2013 on Windows 8 you get some
additional Windows Metro style templates. These
are not available on the other systems, because
WinRT is not available on the previous operating
systems.
Here is a classic "Hello world!" C++ application
using the native XAML framework for the UI.
There is basically no C++ code (other than what
the wizard generated for this type of project).
There is a slider on the top and a block of text
displaying "Hello world". The font size of the
text block is bound to the value of the slider.
Everything is done in XAML.
Collapse | Copy
Code
<Page
x:Class="HelloWorldApp.BlankPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:HelloWorldApp"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{StaticResource ApplicationPageBackgroundBrush}">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="15*"/>
</Grid.RowDefinitions>
<Slider Name="slider" Minimum="20" Maximum="80"
Value="50"
Grid.Row="0" />
<TextBlock Text="Hello world!"
FontSize="{Binding ElementName=slider, Path=Value, Mode=OneWay}"
HorizontalAlignment="Center"
Grid.Row="1" />
</Grid>
</Page>
Conclusion
Visual Studio 2013
brings significant improvements or new features
for native developers. These include new
features from C++11
(although more are expected after the RTM),
updates to the VC++
libraries, improvements to the
VC++ compiler, new
features in the IDE for C++, support for
building Windows 8 Metro-style applications and
others. On the other hand there are very few
improvements in MFC
and, very important, no support for Windows XP
and Windows Server 2003. If your native
applications still target these operating
systems you won't be able to use the new toolset
to build them.
News:
1 UCanCode Advance E-XD++
CAD Drawing and Printing Solution