home *** CD-ROM | disk | FTP | other *** search
- 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.
-