CGAL 6.2 - Manual
Loading...
Searching...
No Matches
Portability Issues
Author
Michael Hoffmann (hoffm.nosp@m.ann@.nosp@m.inf.e.nosp@m.thz..nosp@m.ch)
Stefan Schirra
Sylvain Pion

This chapter gives an overview of issues related to the configuration of CGAL that allow you to answer such questions as:

Also addressed here are issues related to writing code for non-standard-compliant compilers. Compilers have made a lot of progress toward the C++-standard recently. But still they do not fully implement it. There are a few features you may assume; others you may not assume. Especially you may assume that the compiler

  • supports namespaces
  • supports member templates
  • support for std::iterator_traits.

Checking for LEDA or GMP support

In the makefiles included for the compilation of every CGAL program (i.e., those to which the environment variable CGAL_MAKEFILE refers),

we define command line switches that set the flags

CGAL_USE_LEDA, CGAL_USE_GMP

iff CGAL is configured with LEDA or GMP support, respectively.

Using Boost

CGAL code can rely on Boost libraries to some extent.

Boost was shipped with CGAL Release 3.1, and is no longer shipped within CGAL, as it is mainstream, and already distributed with Linux and Cygwin.

Since portability and backward compatibility are a concern in CGAL, we have decided that the list of Boost libraries usable in CGAL will be decided by the CGAL editorial board. The requirements are higher when it appears in the user visible interface than when Boost code is used only internally. Requirements are lower for code that is not released such as the test-suite. Boost libraries already accepted in the C++ Standard Library Technical Report will be the first easy candidates (these are marked [TR1] in the list below). However, wrapping the use within CGAL is generally advised (like what is done in the cpp11 namespace). Finally, the policy is that if a better alternative exists in Boost and is allowed, then CGAL code must use it instead of a CGAL version (which probably must be deprecated and phased out), trying not to break backward compatibility too much.

A list of reasonable Boost libraries to use in the CGAL API is Graph, Parameter (for packages already using it), Property Map, Smart Pointers (for packages already using it), Variant.

Before using a Boost libraries internally, first check whether it is already used, and if not indicate it while submitting your changes (feature, small-feature or pull request), or even by sending an email to cgal-develop during the development.

Using the version-number and configuration macros and flags

Here is a short example on how these macros can be used. Assume you have some piece of code that depends on whether you have LEDA-4.0 or later.

#ifdef CGAL_USE_LEDA
#include <LEDA/basic.h>
#endif
#if defined(CGAL_USE_LEDA) && __LEDA__ >= 400
... put your code for LEDA 4.0 or later ...
#else
... put your code for the other case ...
#endif

Identifying compilers and architectures

Every compiler defines some macros that allow you to identify it; see the following table.

GNU 3.2.1 __GNUC__ 3
GNU 3.2.1 __GNUC_MINOR__ 2
GNU 3.2.1 __GNUC_PATCHLEVEL__ 1
Microsoft VC7.1 _MSC_VER 1310
Microsoft VC8.0 _MSC_VER 1400
Intel 11.1 __INTEL_COMPILER 1110
Clang 2.9 __clang_major__ 2
Clang 2.9 __clang_minor__ 9
SUN 5.3 __SUNPRO_CC 0x530
SUN 5.10 __SUNPRO_CC 0x5100

There are also flags to identify the architecture.

SGI __sgi
SUN __sun
Linux __linux

Known problems and workarounds

Macros connected to workarounds/compilers

Some macros are defined according to the detected compiler. This is done to avoid some ifdefs in our actual code.

CGAL_LITTLE_ENDIAN

set, iff

CGAL_CFG_NO_BIG_ENDIAN is set.

CGAL_BIG_ENDIAN

set, iff

CGAL_CFG_NO_BIG_ENDIAN is not set.

CGAL_DEPRECATED

used to declare a function as deprecated - just add it before the function declaration. You may also surround deprecated code with CGAL_NO_DEPRECATED_CODE, such that it is easy to test if a piece of code uses deprecated code or not:

#ifndef CGAL_NO_DEPRECATED_CODE
CGAL_DEPRECATED void foo(int i)
{
...
}
#endif // CGAL_NO_DEPRECATED_CODE

Various other problems and solutions

min and max

Visual C++ headers (and others) sometimes define min and max as macros. If you write max followed by an opening parenthesis, this can lead to unwanted substitutions. In order to work around it, you should use one of the following tricks:

max BOOST_PREVENT_MACRO_SUBSTITUTION (a, b);
(max) (a, b);
T max(const T &x, const T &y)

Templated member functions

For SunPRO C++ member function templates with dependent return type must be defined in the body of the class.

Function parameter matching

The function parameter matching capacities of Visual C++ are rather limited. Failures occur when your function bar is like

bar(std::some_iterator<std::some_container<T>>....) ...
...
bar(std::some_iterator<std::some_other_container<T>>....) ...

VC++ fails to distinguish that these parameters have different types. A workaround is to add some dummy parameters that are defaulted to certain values, and this affects only the places where the functions are defined, not the places where they are called. This may not be true anymore for recent VC++ versions.

typedefs of derived classes
Microsoft VC++ does not like the following sorts of typedefs that are standard
class A : public B::C {
typedef B::C C;
};
It says that the typedef is "redefinition". So such typedefs should be enclosed by
#ifndef _MSC_VER
#endif
This may not be true anymore for recent VC++ versions.