Mateusz Loskot :: hacking on, working out, living up

Illegal token on right side of

27 Jan 2010 | mloskot

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::min)(); (std::numeric_limits::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 struct Series { T min() { return *(std::min_element(s, s + Size); } T& operator[](int index) { return s[index]; } private: T s[Size]; };

Series 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).

Fork me on GitHub