Certain parts of C are inherently machine dependent. The following potential trouble spots is not meant to be all-inclusive but to point out the main ones.
Purely hardware issues like word size and the properties of floating point arithmetic and integer division have proven in practice to be not much of a problem. Other facets of the hardware are reflected in differing implementations. Some of these, particularly sign extension (converting a negative character into a negative integer) and the order in which bytes are placed in a word, are nuisances that must be carefully watched. Most of the others are only minor problems.
The number of variables declared with register that can actually be placed in registers varies from machine to machine as does the set of valid types. Nonetheless, the compilers all do things properly for their own machine; excess or invalid register declarations are ignored.
The order of evaluation of function arguments is not specified by the language. The order in which side effects take place is also unspecified. For example, in the expression:
a[i] = b[i++]the value of i could be incremented after b[i] is fetched, but before a[i] is evaluated and assigned to, or it could be incremented after the assignment.
The value of a multi-character character constant may be different for different machines.
Fields are assigned to words, and characters to integers, right to left on some machines and left to right on other machines. These differences are invisible to isolated programs that do not indulge in type punning (for example, by converting an int pointer to a char pointer and inspecting the pointed-to storage) but must be accounted for when conforming to externally imposed storage layouts.
The lint program checking tool is useful for finding program bugs and non-portable constructs. For information on how to use lint(CP), see ``lint analyzer''.