Assertions are a more systematic alternative to macros in writing conditionals to test what sort of computer or system the compiled program will run on. Assertions are usually predefined, but you can define them with preprocessing directives or command-line options.
The macros traditionally used to describe the type of target are not classified in any way according to which question they answer; they may indicate a hardware architecture, a particular hardware model, an operating system, a particular version of an operating system, or specific configuration options. These are jumbled together in a single namespace. In contrast, each assertion consists of a named question and an answer. The question is usually called the predicate. An assertion looks like this:
#predicate (answer)
You must use a properly formed identifier for predicate. The value of answer can be any sequence of words; all characters are significant except for leading and trailing whitespace, and differences in internal whitespace sequences are ignored. Thus, `x + y' is different from `x+y' but equivalent to `x + y'. `)' is not allowed in an answer.
Here is a conditional to test whether the answer answer is asserted for the predicate predicate:
#if #predicate (answer)
There may be more than one answer asserted for a given predicate. If you omit the answer, you can test whether any answer is asserted for predicate:
#if #predicate
Most of the time, the assertions you test will be predefined assertions.
GNU C provides three predefined predicates: system
, cpu
,
and machine
. system
is for assertions about the type of
software, cpu
describes the type of computer architecture, and
machine
gives more information about the computer. For example,
on a GNU system, the following assertions would be true:
#system (gnu) #system (mach) #system (mach 3) #system (mach 3.subversion) #system (hurd) #system (hurd version)
and perhaps others. The alternatives with more or less version information let you ask more or less detailed questions about the type of system software.
On a Unix system, you would find #system (unix)
and perhaps one of:
#system (aix)
, #system (bsd)
, #system (hpux)
,
#system (lynx)
, #system (mach)
, #system (posix)
,
#system (svr3)
, #system (svr4)
, or #system (xpg4)
with possible version numbers following.
Other values for system
are #system (mvs)
and #system (vms)
.
Portability note: Many Unix C compilers provide only one answer
for the system
assertion: #system (unix)
, if they support
assertions at all. This is less than useful.
An assertion with a multi-word answer is completely different from several
assertions with individual single-word answers. For example, the presence
of system (mach 3.0)
does not mean that system (3.0)
is true.
It also does not directly imply system (mach)
, but in GNU C, that
last will normally be asserted as well.
The current list of possible assertion values for cpu
is:
#cpu (a29k)
, #cpu (alpha)
, #cpu (arm)
, #cpu
(clipper)
, #cpu (convex)
, #cpu (elxsi)
, #cpu
(tron)
, #cpu (h8300)
, #cpu (i370)
, #cpu (i386)
,
#cpu (i860)
, #cpu (i960)
, #cpu (m68k)
, #cpu
(m88k)
, #cpu (mips)
, #cpu (ns32k)
, #cpu (hppa)
,
#cpu (pyr)
, #cpu (ibm032)
, #cpu (rs6000)
,
#cpu (sh)
, #cpu (sparc)
, #cpu (spur)
, #cpu
(tahoe)
, #cpu (vax)
, #cpu (we32000)
.
You can create assertions within a C program using `#assert', like this:
#assert predicate (answer)
(Note the absence of a `#' before predicate.)
Each time you do this, you assert a new true answer for predicate. Asserting one answer does not invalidate previously asserted answers; they all remain true. The only way to remove an assertion is with `#unassert'. `#unassert' has the same syntax as `#assert'. You can also remove all assertions about predicate like this:
#unassert predicate
You can also add or cancel assertions using command options
when you run gcc
or cpp
. See section Invoking the C Preprocessor.