STLplus C++ Library Collection - portability/portability_fixes.hpp - Macros for Fixing Compiler Differences
Author: Andy Rushton

# STLplus C++ Library Collection

Website Collection Library

# portability/portability_fixes.hpp
Macros for Fixing Compiler Differences

- Browse Header portability_fixes.hpp
- Introduction
- MSWINDOWS Macro
- Silencing Unnecessary Warnings
- minimum/maximum Template Functions
- Missing sleep function on Windows
- stlplus::little_endian function

## Introduction

This component contains a set of macros which provide optional debug code. The debug code is optional in the sense that it can be entirely stripped out when compiling a release version of software. It is also optional in that a program compiled for debugging will still not produce any debug output unless it is switched on through the environment.

## MSWINDOWS Macro

It irritated me that I had to check for two mutually-exclusive macros when writing Windows-specific code - _WIN32 and _WIN32_WCE. So I have simply defined a single macro MSWINDOWS which is defined if either of the above macros is defined.

You can use the same macro in your own Windows-specific code:

    #include "portability_fixes.hpp"
    ...
    #ifdef MSWINDOWS
      // Windows-specific bits
      ...
    #else
      // Generic Unix bits
      ...
    #endif

## Silencing Unnecessary Warnings

In principle, it is a good policy to make code compile with no warnings. However, this is sometimes not possible because there are some compiler warnings that simply cannot be avoided. This is not lazy programming - I'm talking about warnings that are unfixable because of problems with the compiler or assumptions by compiler writers.

In the portability_fixes header I include some pragmas for switching off these unfixable warnings so that it is possible to compile code warning-free.

### Visual Studio

I switch off the following warnings in Visual Studio:

Unfixable warning in Visual Studio
ID | Description
--- | ---
4275 | VC6, exported class was derived from a class that was not exported
4786 | VC6, identifier string exceeded maximum allowable length and was truncated (only affects debugger)
4305 | VC6, identifier type was converted to a smaller type
4503 | VC6, decorated name was longer than the maximum the compiler allows (only affects debugger)
4309 | VC6, type conversion operation caused a constant to exceeded the space allocated for it
4290 | VC6, C++ exception specification ignored
4800 | VC6, forcing value to bool 'true' or 'false' (performance warning)
4675 | VC7.1, "change" in function overload resolution _might_ have altered program
4996 | VC8, 'xxxx' was declared deprecated

### Borland Compiler

Unfixable warning in Borland
ID | Description
--- | ---
8008 | Condition is always true. Whenever the compiler encounters a constant comparison that (due to the nature of the value being compared) is always true or false, it issues this warning and evaluates the condition at compile time.
8060 | Possibly incorrect assignment. This warning is generated when the compiler encounters an assignment operator as the main operator of a conditional expression (part of an if, while, or do-while statement). This is usually a typographical error for the equality operator.
8066 | Unreachable code. A break, continue, goto, or return statement was not followed by a label or the end of a loop or function. The compiler checks while, do, and for loops with a constant test condition, and attempts to recognize loops that can't fall through.

All of these tend to happen a lot in template functions.

## minimum/maximum Template Functions

The STL defines two template functions called std::min and std::max which return the minimum and maxuimum of two values respectively.

However, the Windows headers up to and including Visual Studio v6 define macros called max/min which conflict with the templates std::max and std::min. To avoid conflicts, Microsoft removed the std::max/min from their version of the STL rather than fixing the problem!

Fortunately, from Visual Studio .NET (version 7) the STL templates have been added correctly.

I could have fixed this by providing my own min/max for Visual Studio version 6, but this could potentially have broken the MFC headers.

So, instead, I've created extra template function definitions minimum/maximum that avoid all the problems above.

    template<typename T> const T& stlplus::maximum(const T& l, const T& r) {return l > r ? l : r;}
    template<typename T> const T& stlplus::minimum(const T& l, const T& r) {return l < r ? l : r;}

Use these functions to avoid the min/max problem.

## Missing sleep function on Windows

On Unix, there is a function `sleep(unsigned seconds)` That causes the program (actually, just the current thread) to go to sleep for the specified interval. On Windows, this is implemented as `Sleep(DWORD millseconds)`. To make programs just a little easier to write, I implemented a `sleep(unsigned seconds)` function on Windows.

## stlplus::little_endian function

Different machine architectures store data using different byte orders. This is referred to as Big- and Little-Endian Byte Ordering.

The issue is: where does a pointer to an integer type actually point? The least-significant or the most-significant byte?

Big-Endian
  Byte 0 = The most significant byte
Little-Endian
  Byte 0 = The least significant byte

In other words, bytes are addressed from offset 0 upwards. This means that in big-endian order byte 0 is the msB, whereas in little-endian order byte 0 is the lsB.

For example, Intel-based machines store data in little-endian byte order.

This function establishes byte order at run-time:

    bool stlplus::little_endian(void);