Portability issues
==================
As released, the XaAES beta7+ source archive compiles and works under
Lattice C and GCC and it would be nice if it could be kept that way.
TurboC/PureC compatibility would also be nice, but I have not been able
test that now (and I'm not sure it has ever really worked before).

HR: Well, Beta 8 is based on Pure C.
    And because Pure C can do nothing but ANSI, there should be no problem
    with other ANSI compilers.
    NB: I carefully kept using short for int.
	NB: v0.8 doesnt need the mintlib anymore, which greatly reduces
	    porting efforts.

Naturally, not all developers have access to more than one compiler, but
it's not really difficult to stay out of trouble.

The most important thing to remember is that an 'int' is a 16 bit number
when compiled with TurboC/PureC and GCC (as set up in the Makefile),
while it's 32 bit under Lattice C (as set up in the Makefile/.PRJ).
For TurboC/PureC there's no way to change this, but the other two
compilers can actually handle both sizes (if you change this, there's
no telling what might happen, though ;-).

To avoid problems with integers, the following rules go a long way:

- Don't use the 'int' type at all!
  There are none in the XaAES source right now and there's no reason
  to add any. Use 'short' and 'long' as appropriate.

- Always make sure that you avoid overflowing 16 bit 'int'!
  Unless anything else is specified, C defines that arithmetic should
  be done with numbers of the type 'int'. This means that with Lattice,
  the following will always be fine
     mem = malloc(n * s);          /* short n, s; */
  since the multiplication will yield an 'int' with the correct result.
  With the other two compilers, the 'int' is 16 bit and so will the
  result be, which means the result of the multiplication will not be
  correct if it doesn't fit in 16 bits.
  The way around this is to make sure the calculation is done with
  'long' numbers, since that guarantees a 'long' result:
     mem = malloc((long)n * s);    /* short n, s; */
  Notice that it's enough to cast one of the numbers to 'long'.
  if an ordinary digit, like '2', is an 'int', while '2L' is a 'long'.
  A similar thing which is easy to miss is when a shift is used:
     mask = number << 16;          /* long mask;    short number; */
  When 'int' is 16 bit, the result will always be 0 above.

Other potential problems can be found in areas where the ANSI standard
doesn't specify something, such as whether a 'char' is signed or not:

- Be careful with 'char' variables that are used in calculations!
  In some compilers 'char' is unsigned and in others it's signed.
  Sometimes this can even be changed via switches/options.
  This means that for example
     sum += c;                     /* short sum;    char c = 0xff; */
  will add 255 to 'sum' if 'char' is unsigned and subtract 1 if
  'char' is signed.
  If you need to do something like the above, specify signed/unsigned
  explicitly.

Some compilers implement extensions to the ANSI standard, but others
may not understand those:

- Multi-character constants are not part of the ANSI standard and
  GCC does not support them. So, instead of using for example
     if (cookie == 'MiNT')
  you'll have to compare with a number. Naturally, a #define or
  a comment is a good idea when you do this kind of thing.

- C++ style comments
     //  This is a comment
  are not part of ANSI C and may not work on all compilers.
  Stay with the normal C comments.

- Nested comments are not supported by all compilers.
  A better way to remove code temporarily is to use #if 0 ... #endif.

Include files are not always quite the same on all the compilers.
Currently we use the MiNT libs, though, so this should not be a problem.

Using uppercase letters for include file names can cause problems for
some compilers on some file systems, so avoid that.
