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

WOGIS 2010 Conference by OSGeo Poland

OSGeo FoundationTomasz Kubik from OSGeo Polish Chapter announced WOGIS 2010 conference:

This is the second conference on open software organized by the Institute of Geodesy and Geoinformation Science, Wroclaw University of Environmental and Life Sciences, and the Polish Chapter of OSGeo.

Check the WOGIS 2010 conference website for details.

Mouse vs keyboard quotes of the day

My two favourite quotes I’ve remembered from today’s thread about programming using a proportional font and other stuff that happened on, as busy as always, ACCU mailing list:

For me, when coding I think fast and I type just as fast, and every time I have to touch that stupid mouse I curse the idiot who failed to add or, worse, removed (which seems to happen as software “evolves”) the menus/shortcuts/tabbing-logic that would allow me never to lose my thread, or efficiency.

— Matthew

and

I’ve watched people using IDEs (mainly on Windows) and usually I wonder if I’m going to die of old age before they finish carrying out various simple editing tasks by searching through menu trees, navigate through dialogue boxes, clicking on this option and that option (…) I often wonder if I should only have to work 20 hour weeks as I can get my typing-in work done twice as quickly as some other people :)

— Stewart

Signed, with both hands.

Quick CMake of GEOS

It’s an example of b***dy quick attempt to configure CMake-based build of a fairly large library written in C++ programming language. It is GEOS.

Seven. A lucky number. Arnulf‘s nickname. Total number of lines (commands) of CMake script to configure build of GEOS C++ core as a static library using sources form SVN trunk:

Create trunk/CMakeLists.txt file:

project(geos)
cmake_minimum_required(VERSION 2.6)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
add_subdirectory(src)

Create trunk/src/CMakeLists.txt file:

include_directories(${CMAKE_SOURCE_DIR}/include)
file(GLOB_RECURSE geos_SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
add_library(geos STATIC ${geos_SRC})

In fact, only six lines are really required. The third line in file trunk/CMakeLists.txt is optional.

mloskot@dog:~/dev/geos/_svn/trunk$ svn status
?       CMakeLists.txt
?       src/CMakeLists.txt
mloskot@dog:~/dev/geos/_svn/trunk$ mkdir ../build
mloskot@dog:~/dev/geos/_svn/trunk$ cd ../build/
mloskot@dog:~/dev/geos/_svn/build$ cmake ../trunk
-- The C compiler identification is GNU
-- The CXX compiler identification is GNU
-- Check for working C compiler: /usr/bin/gcc
-- Check for working C compiler: /usr/bin/gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/mloskot/dev/geos/_svn/build
mloskot@dog:~/dev/geos/_svn/build$
mloskot@dog:~/dev/geos/_svn/build$ make -j5
Scanning dependencies of target geos
[  0%] Building CXX object src/CMakeFiles/geos_lib.dir/operation/valid/RepeatedPointTester.cpp.o
...

and 53 seconds later my Intel Core 2 Duo 2.4GHz box announces:

[100%] Building CXX object src/CMakeFiles/geos.dir/linearref/LengthIndexOfPoint.cpp.o
Linking CXX static library libgeos.a
[100%] Built target geos

This build configuration is universal and cross platform, thus should work on all platforms supported by CMake.

Simply, you can not afford not use the best cross-platform build system that ever existed :-)

PostGIS 1.5.0 will require GEOS 3.1.0+

PostGIS spatial database extension for PostgreSQLPostGirls and PostBoys, be prepared!

The upcoming release of PostGIS 1.5.0 (available as beta1 beta2) will require GEOS in version 3.1.0 or later.

The beta1 testing results suggested to bump the minimum GEOS version to 3.1.0. The GEOS requirement issue was one of the heavily discussed topics on the postgis-devel this month.

The PostGIS team is going to give GEOS a nice present for its 10th round month birthday.

Exceptions to error codes translation made simple

On many occasions, it is not possible or it’s even forbidden to let an exception thrown to sneak out of a function. On many occasions, it is necessary to sink all exceptions in place where they may occur and translate exceptions thrown to error codes. I have observed it’s not uncommon software projects stick to some rules about how they handle exceptions, like:

  • I’m sorry, I don’t like the fat & slow hippo RTTI (BTW, hippo can run 50 km/h!).
  • My function, class, library never ever throws exceptions.
  • I use exceptions to signal error conditions only from and within internal components, but never let them to cross the line drawn by public interfaces.
  • I write C wrapper for C++ library, I have to translate exceptions to error codes.
  • Exceptions? I have no idea who was mad enough to invent such a $%&@ beast. Forget!

Shortly, not for everyone exceptions are kosher, gluten and lactose-free meals.

Even if exceptions are not kosher, it is necessary to love & deal with them because…use of standard library elements or 3rd-party components which may throw, coding conventions ignorance within a team, just-in-case prevention, etc. Handling exceptions may make code very messy (check how Java camp deals database connection problems). It is possible to handle exceptions and maintain clean code.

Any fool can write code that a computer can understand. Good programmers write code that humans can understand.

Martin Fowler

Below is a simple example showing how to solve some of the problems pointed above. The basic idea is to implement one-for-all exceptions handler where all types of exceptions possible to be thrown are killed and translated to specified error code, exceptions have chance to send S.O.S. code before sinking.

#include <cassert>
#include <exception>
#include <iostream>
#include <stdexcept>

template <typename T>
inline T const& handle_exception(char const* const who, T const& rc)
{
    try
    {
        throw;
    }
    catch (int e)
    {
        std::cerr << who << " caught int: " << e << std::endl;
    }
    catch (char const* e)
    {
        std::cerr << who << " caught c-string: " << e << std::endl;
    }
    catch (std::exception const& e)
    {
        std::cerr << who << " caught std::exception: " << e.what() << std::endl;
    }
    return rc;
}

#define EXCEPTION_TRY() \
    try {

#define EXCEPTION_CATCH_AND_RETURN(success, failure) \
    } catch (...) { \
        return handle_exception(__FUNCTION__, failure); \
    } \
    return success;

// use it to exit void function on error
#define EXCEPTION_CATCH_AND_EXIT() \
    } catch (...) { handle_exception(__FUNCTION__, false); \
    return; }

template <typename T>
class number
{
public:
    // public ctor, may throw
    number(T value) : value_(value)
    {
        if (value != value)
            throw "value is NaN";
    }

    // public save division, never throws
    bool divide_s(double& result, T const& den) const
    {
        EXCEPTION_TRY()
        result = divide_(value_, den);
        EXCEPTION_CATCH_AND_RETURN(true, false)
    }

private:
    T value_;
    // used internally by private methods, allowed to throw
    double divide_(T const& num, T const& den) const
    {
        if (den > 0)
        {
            return num / den;
        }
        throw std::invalid_argument("denominator is zero");
    }
};

// C wrapper is not allowed to throw exceptions
double divide_numbers(double num, double den)
{
    EXCEPTION_TRY()

    number<double> n(num);
    double r = 0;
    n.divide_s(r, den);

    EXCEPTION_CATCH_AND_RETURN(true, false)
}

int main()
{
    bool success(false);
    double result(0);

    // Using C++ interface
    {
        number<int> n(10);
        // no error logged
        success = n.divide_s(result, 2);
        assert(success);
        // error logged, error code returned
        success = n.divide_s(result, 0);
        assert(!success);
    }
    // Using C interface
    {
        // no error logged
        result = divide_numbers(10, 2);
        // error logged
        result = divide_numbers(10, 0);
        // error logged
        float nan = 0;
        result = divide_numbers(nan / 0, 10);
    }
}

It’s simple and not ideal, but it did the job very well for myself and number libraries. Certainly, there are is a room for improvements. The logging mechanism is a simple one. It’s a good idea to add catch clauses for other types, even for int, especially if one has to deal with throw __LINE__; signals.

There is a lot of googlefindable articles and books one can buy. Here is the (incomplete) list of favourites guidelines:

Thanks to wonderful ACCU folks for a very interesting brainstorm on similar topic we had one day. Comments, improvements and bug reports would be greatly appreciated.