Debugger visualizers in Visual Sudio 11 Developer Preview

Visual Studio 11 Developer Preview introduces new style debugger visualizers. The autoexp.dat definition of templates in previous versions of the Visual Studio debugger is being replaced with new style definitions based on XML and stored in defaultvis.natvis file.

Microsoft explains the motivation behind redesigning the native type visualization mechanism is to give better diagnostic reporting (visualizer expressions can be now evaluated and displayed in the output window to help debugging .natvis file), provide XSD schema defining type definition, support of multiple files for type definition: system-wide in %ProgramFiles%\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\defaultvis.natvis and user-defined in %USERPROFILE%\My Documents\Visual Studio Dev11\Visualizers\xxx.natvis.

It sounds really good and has a great usability potential for programmers who uses C++ generative programming capabilities, defines complex C++ types, heavily uses C++ Standard Library and Boost C++ Libraries.

Here is example of new style visualizer defined in XML copied from the defaultvis.natvis:

  <!--std::unique_ptr from <memory>-->
  <Type Name="std::unique_ptr<*>">
    <DisplayString Condition="_Myptr == 0">empty</DisplayString>
    <DisplayString>unique_ptr {*_Myptr}</DisplayString>
    <Expand>
      <Item Name="[ptr]" Condition="_Myptr != 0">_Myptr</Item>
    </Expand>
  </Type>

For most types from C++ Standard Library and Windows SDK, the new visualizers work very well. However, the currently available Visual Studio 11 Developer Preview (Version 11.0.40825.2 PREREL) is shipped with incorrect definitions in the defaultvis.natvis. The C++TR1 definitions introduced in Visual Studio 2008 are only forwarded (aliased) from std:tr1:: to std:: in Visual Studio 2010. In Visual Studio 11, they have completely moved from std::tr1:: to std:: to align with C++11 standard. But, the new visualizers in defaultvis.natvis define templates are still referring to the C++11 types in std::tr1:: namespace.

This prevents the correct visualization for types like std::shared_ptr:

vs11-visualizers-broken-2

There is an easy workaround possible:

  1. Make private copy of defaultvis.natvis in %USERPROFILE%\My Documents\Visual Studio Dev11\Visualizers\xxx.natvis where xxx is your preferred name.
  2. Open xxx.natvis in a text editor.
  3. Find std::tr1:: and replace with std::.
  4. Save the changes and relaunch the Visual Studio 11.
  5. You should see objects of the C++11 types correctly visualized.

vs11-visualizers-fixed-3

I have reported this issue to Microsoft Connect in Incorrect Type Name references in defaultvis.natvis visualizers for standard library ticket.

illegal token on right side of ‘::’

libLAS - ASPRS LiDAR data translation toolsetOne of libLAS users reported that when use of #include <liblas/lasreader.hpp> in his application compiled with Visual C++ 10.0 from Visual Studio 2010 cause this error:

utility.hpp(253): error C2589: '(' : illegal token on right side of '::'

The error is an incarnation of a very well-known problem in Visual C++ when using the C++ Standard Library elements, especially the Standard Template Library, in Windows API-based programs. As libLAS library does use the C++ library, so does a user’s application if includes libLAS headers.

The problem is caused by conflicting definitions of min() and max() macros defined in windef.h header. Macros in C++ are scope-less evil, especially if defined in public headers using such extremely unique names as min or max. The fact that Microsoft defined it way before C++ was born absolves them at large, but for the Spirit sake, they should learn the lesson and disable it for good in C++ mode (but not yet another MS-specific way!). No one who’s sane need or want to use them!

Pie in the sky. In the meantime, C++ programmers as the libLAS user who reported this problem have to deal with it on their own. The easiest way is to check CodeProject or Q143208 or search (not google) for solution like #define NOMINMAX for Visual C++ compiler.

However, is another option is to apply a simple trick to call of *::min() or *::max() functions (i.e. std::min() or std::max() which effectively prevents macro substitution, so the Visual C++ compiler (or any other compiler with similar problem) does not complain about illegal token. The trick is to wrap function name, fully qualified name, with parentheses:

(std::min)(x, y);

In most cases of use of C++ Standard Library as described above, it is required for the following functions:

(std::min)(x, y);
(std::max)(x, y);
(std::numeric_limits<T>::min)();
(std::numeric_limits<T>::max)();

In case a user-defined type has a member function with exactly the same name as a macro present in global scope (macros always live in global scope!), it may be necessary to apply the very same trick when a member function is called on an object:

template <typename T, int Size>
struct Series
{
  T min() { return *(std::min_element(s, s + Size); }
  T& operator[](int index) { return s[index]; }
private:
  T s[Size];
};

Series<int, 3> s;
s[0] = 2;
s[1] = 3;
s[2] = 1;

int m = (s.min)(); // long way, but here is the trick

There is one side effect which may be an inconvenience. This trick disables argument dependent name lookup (ADL, aka Koenig lookup).

Traits of void

Long time ago, I reported bug to Visual C++ 9.0 (Visual Studio 2008 SP1) complaining that has_trivial_destructor applied to void returns true (ID:458570). I also discussed it with folks on comp.std.c++ where, among quite different voices, Pete Becker writes:

[tr.meta.req]/8 in TR1 requires is_pod::value to be 1. n2857 is not a standard, and implementations of previous standards are not wrong for not doing what isn’t yet required of them.

and later concludes:

Under the current standard, using the name std::is_pod requires a diagnostic. So if you want to be literal, both compilers are “wrong”. Nevertheless, neither is really “wrong”, they just implement different non-standard versions of is_pod.

So, Visual C++ might actually not be wrong. Fair enough.

Today, I got back to this issue for a while a little extending my test program to use the type traits from both, TR1 and C++0x:

#include <iostream>
#include <tr1/type_traits>
int main()
{
using std::cout; using std::endl;
cout << std::tr1::is_pod<void>::value << endl;
cout << std::tr1::has_trivial_destructor<void>::value << endl;
cout << std::is_pod<void>::value << endl;
cout << std::has_trivial_destructor<void>::value << endl;
}

and compiled it with GCC 4.4.1:

$ g++ -Wall -pedantic -std=c++0x void.cpp
$ ./a.out
1
1
0
0

Now, my confusion has been raised to the power of 2. This is clearly a Polnische Wirtschaft or Czech movie or Turkish sermon

…let’s try to ask libstdc++ folks.

Got new toy

I’ve just got new toy tool. Since yesterday, I’m a happy owner of the most standards-conformant C++ compiler that ever existed – Comeau C/C++ from Comeau Computing.

I’ve successfully installed Comeau C/C++ 4.3.10.1 Beta compiler and libcomo36, accompanying Standard C++ Library, on 32-bit version of latest Ubuntu 9.04.

I’m going to use Comeau C/C++ for purposes like analysis and review of C++ source code I write or use, verification of code portability as well as for learning elements of C++ and experimenting. This is excellent compiler for learning C++ language. Among loads of features, one of the coolest is ability to give clear and informative error messages. This is very helpful while working with complex class and function templates.

Continue reading

SOCI 3.0.0 RPM Packages

Denis Arnaud prepared RPM packages for SOCI library version 3.0.0. As Denis explains, these RPM packages primarily target Fedora family, but should work on other RPM-based distributions.

Currently, SOCI 3.0.0 RPM packages are available to download from Open Travel Request Parser project website. By the way, I’ve revealed Open Travel Request Parser uses SOCI, it’s really nice.

SOCI is a database access library for C++ that makes the illusion of embedding SQL queries in the regular C++ code, staying entirely within the Standard C++. It also fits very well to the world of templates defined in C++ Standard Library and offers extensive integration with data types from Boost C++ Libraries like optional, tuple and fusion:

Rowset rs = (sql.prepare << "select name from persons");
std::copy(rs.begin(), rs.end(), std::ostream_iterator(cout, "\n"));

Not to mention the coolness of flexible support for user-defined types.

Generic Geometry Library

Two months ago Barend Gehrels announced on the OSGeo Discuss list ongoing Open Source project called Generic Geometry Library, GGL in short.

The Generic Geometry Library provides a generic implementation of geometry algorithms, working with geometry types provided by the library itself as well as user-defined types. The library is implemented in C++ programming language with extensive use of elements of metaprogramming like class (type) templates, static polymorphism and compile-time execution. Consequently, GGL is built upon two of the greatest pieces of C++ code ever written by humanity: C++ Standard Library and Boost C++ Libraries.

In my opinion, this project is valuable and have potential which may interest many of us, FOSS4G users and developers. The OSGeo Foundation agreed to host this mailing list ggl@lists.osgeo.org dedicated to discussions development and use of the Generic Geometry Library.