www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1994/11/30/09:30:08

From: ANTHONY APPLEYARD <A DOT APPLEYARD AT fs1 DOT mt DOT umist DOT ac DOT uk>
To: DJGPP AT SUN DOT SOE DOT CLARKSON DOT EDU
Date: Wed, 30 Nov 1994 09:26:04 GMT
Subject: Preprocessor information

  In reply to former criticism of statements by me about use of Tex, here is
the preprocessor part of the INFO, reformatted and edited into ascii 614 lines
for e.g. printing out as a paper reference copy, since (unless you have two
PC's), you can't easily read an on-screen online help system while the screen
and CPU are occupied with a text editor that you are editing a program on!
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[THE GNU C PREPROCESSOR]
  ---------------------------------
[CONTENTS]
Parameter options that gcc passes on to the preprocessor
Preprocessor Commands
Conditionals
Transformations that are made always
Header Files
Files that you only want to be included once
Macros
Predefined Macros
Stringification
Concatenation
Pitfalls and Subtleties of Macros:-
  A name supplied by macro expansion can be treated as another macro name
  Bracket and operator precedence trouble
  Swallowing the Semicolon
  Duplication of Side Effects
  Self-Referential Macros
  Separate Expansion of Macro Arguments
  Cascaded Use of Macros
  Newlines in Macro Arguments; their effect on error message line numbers
C Preprocessor Output
To call the preprocessor directly

  ---------------------------------
[PARAMETER OPTIONS THAT GCC PASSES ON TO THE PREPROCESSOR]
-A `predicate'(`answer')     Make an assertion with that predicate and answer,
-A-       Disable all predefined assertions; it also undefines all predefined
          macros that identify the type of target system.
-C        Do not discard comments: pass them through to the output file.
          Comments appearing in arguments of a macro call will be copied to
          the output before the expansion of the macro call.
-D `name'  Predefine `name' as a macro, with definition `1'.
-D `name'=`definition'      Predefine `name' as a macro, with that definition.
          If you are in a shell or shell-like program (e.g. DOS) you may need
          to use its quoting syntax to protect characters such as spaces that
          have a meaning in its syntax. If you use more than one `-D' for the
          same `name', the rightmost definition takes effect.
-dD       Like `-dM', but does <not> include the predefined macros, and it
          outputs <both> the `#define' commands and the result of
          preprocessing. Both kinds of output go to the standard output file.
-dM       Output a list of `#define' commands for all the macros defined
          during the execution of the preprocessor, including predefined
          macros. Do not output a preprocessed program file.
-H        Print the name of each header file used.
-I `directory'        Add the directory to the end of the list of directories
          to be searched for header files (see `Include Syntax'). These
          directories are searched before the system header file directories.
          If you use more than one `-I' option, the directories are scanned in
          left-to-right order; the standard system directories come after.
-I-       For `#include <`file'>', do not search directories specified by `-I'
          <before> the `-I-'. For `#include "`file'"', do not automatically
          search the current directory.
-idirafter `dir'      Add the directory `dir' to the second #include path. The
          directories on the second include path are searched when a header
          file is not found in any of the directories in the main include path
          (the one that `-I' adds to).
-imacros `file'       Process `file' as input, discarding the resulting
          output, before processing the regular input file. The effect is to
          read the macros and assertions defined in `file'.
-include `file'       Process `file' as input, and include all the resulting
          output, before processing the regular input file.
-iprefix `prefix'     Specify `prefix' as the prefix for subsequent
           `-iwithprefix' options.
-isystem `dir'   Add a directory to the beginning of the second include path,
           marking it as a system directory, so it gets the same special
           treatment as the standard system directories.
-iwithprefix `dir'    Add a directory to the second include path. The
           directory's name is made by concatenating `prefix' and `dir', where
           `prefix' was specified previously with `-iprefix'.
-M        Output a `make' rule describing the main source file's dependencies.
          It will contain its object file name, a colon, and the names of all
          the included files. It may be split into several lines using
          `\'-newline. Do not output a preprocessed program file.
-M -MG    As -M, and treat missing header files as generated files and assume
          they live in the same directory as the source file. `-M -MG' must
          both be specified. Used in automatic updating of makefiles.
-MD `file'            Like `-M', but write the dependency information to
          `file'. Also compile the file as specified. When invoking gcc, do
          not specify the `file' argument: gcc will create file names made by
          replacing ".c" with ".d" at the end of the input file names. In
          Mach, the utility `md' merges multiple dependency files into a
          single dependency file suitable for `make'.
-MM [-MG]  Like `-M' but mention only the files included with `#include
          "`file'"'. Files included with `#include <`file'>' are omitted.
-MMD `file'           Like `-MD' but mention only user header files, not
          system header files.
-nostdinc Do not search the standard system directories for header files, but
          only the directories you have specified with `-I' options (and the
          current directory, if appropriate).
-nostdinc++           Do not search for header files in the C++-specific
          standard directories, but do still search the other standard
          directories. (This option is used when building libg++.)
-P        Do not generate `#'-lines with line-number information in the output
          from the preprocessor.
-pedantic  Issue warnings required by the ANSI C standard in certain cases
          such as when text other than a comment follows `#else' or `#endif'.
-pedantic-errors     Like `-pedantic', except that errors are produced rather
          than warnings.
-traditional          Try to imitate the behavior of old-fashioned C, as
            opposed to ANSI C:-
          Look for macro calls inside strings and character constants.
          Look for macro arguments inside strings and character constants
            in macro bodies when expanding macros.
          End of line terminates string or character constant, with no error.
          Comment is equivalent to no text at all, not whitespace.
          It treats e.g. `1.0e+4' as 3 tokens `1.0e', `+', and `4', not a
            "preprocessing number"..
          A macro that calls itself causes an infinite recursion fault.
          `#' has no special meaning within a macro definition.
          The text at the end of a macro expansion can run together with the
            text after the macro call, to produce a single token.
          `\' inside a macro argument suppresses the syntactic significance of
            the next character.
-trigraphs   Process ANSI standard trigraphs. These are three-character
          sequences, all starting with `??', that are defined by ANSI C to stand for single characters. For example, `??/' stands for `\', so
          `'??/n" means a newline. Forget about trigraphs.
-U `name' Do not predefine `name'. If both `-U' and `-D' are specified for one
          name, the `-U' beats the `-D' and the name is not predefined.
-undef    Do not predefine any nonstandard macros.
-Wall     Requests `-Wtrigraphs' and `-Wcomment' (but not `-Wtraditional').
-Wcomment Warn whenever a comment-start sequence `/*' appears in a comment.
-Wtrigraphs     Warn if any trigraphs are encountered, if they are enabled.
-Wtraditional         Warn about certain constructs that behave differently in
          traditional and ANSI C.

  ---------------------------------
[PREPROCESSOR COMMANDS]
#include <`file'>        Searches for the named file in a list of directories
                         specified by you, then in a standard list of system
                         directories. Comments are not recognized within the
                         `<...'>. `>' terminates argument. Includes the file.
#include "`file'"        Searches for the named file first in the current
                         directory, if the `-I-' option is not used. Then as
                         `#include <`file'>'. `"' terminates the argument.
                         `\' in `file' is treated as an ordinary character.
#include `anything else' Tries to expand the `anything else' as macros. If
                         this finally produces a legal `#include ...' command,
                         this is obeyed as usual.
#include_next            In an #include'd file, same as #include, but in the
                         directory search list it searches only in the
                         directories <after> the directory that the current
                         file was found in.
#define `name' `body'    define a simple macro.
#define `name(`arguments') `body'    define a macro with arguments.
#undef `name'            undefine the argument named.
#if....                  (see `Conditionals' below)
#assert `predicate' (`answer')     Define an assertion as stated. `predicate'
                         is a properly formed identifier. `answer' can be any
                         sequence of words; all characters are significant
                         except leading and trailing whitespace; differences
                         in internal whitespace sequences are ignored.
                         `)' is not allowed in an answer.
          Gnu C provides these sets of predefined assertions:-
          #system(...)       what type of software
          #cpu(...)          what type of computer architecture
          #machine(...)      more information about the computer
#unassert `predicate' (`answer')    Undefine that assertion.
#unassert `predicate'    Undefine that predicate for all its answers.
#error `text'            Cause a fatal error with `text' as the fault message.
#warning `text'          Cause a warning with `text' as the fault message.
#line `n'                The next line will be noted as being line n.
#line `n' "`filename'"   Ditto; also note its filename to be as stated here.
                         Useful when the C program has been generated from
                         another file by some program such as `bison', so
                         that `__FILE__' and `__LINE__' are as the original.
#line `anything else'    Look for macro calls in the `anything else', to
                         try to expand it to a legal form to obey it.
                         `#line' commands alter the results of the `__FILE__'
                         and `__LINE__' predefined macros from that point on.
#               (by itself): Ignored. Included for compatibility with old C's.
#pragma `text'           Passed onto compiler.
#ident                   (followed by a line of text):
                         Ignored. Included for compatibility.

  ---------------------------------
[CONDITIONALS]
  A `conditional' is a command that allows a part of the program to be ignored
<during compilation>, on some conditions. It can test an arithmetic expression
or whether a name is defined as a macro. It does <not> compile into a runtime
conditional test.

#if `expression'            Only read the text if the expression evaluates
`text'                      to non-zero. The text can contain other
#endif                      preprocessor commands including #if...#endif.
  ..........
#if `expression'            If the expression evaluates to non-zero, read
`text1'                     text1, else read text2. The text can contain other
else                        preprocessor commands including #if...#endif.
`text2'
#endif
  ..........
#elif `expression'          This layout
`text'
#endif
  ..........
#else                       means the same as this layout.
#if `expression'
`text'
#endif
#endif
  ..........
#if 0                       Always skip the text. In the text, any #if ...
`text'                      #endif must be in matching pairs, and all ' and "
#endif                      must be in matching pairs as in C.
  ..........

[NOTES]
  A comment (such as the #if condition repeated in /* */) after the `#endif'
is not required, but it is a good practice because it helps to match the
`#endif' to the corresponding `#if'.
  `expression' is a C expression of integer type, which may contain:-
  - Integer constants, all regarded as `long' or `unsigned long'.
  - Character constants. Some are negative if the C compiler used to compile
the preprocessor treats `char' as signed rather than unsigned.
  - Arithmetic operators + - * / % & ! | ^ << >> < == > <= >= && ||
  - Macro calls.
  - <All> other identifiers are treated as zero, including enum-type values.
  - `sizeof' operators are not allowed.
  - A call of   defined(`xxx')   , where `xxx' is a macro name.
    It returns 1 if the macro currently is defined, else 0.
  There also are:-
#ifdef `name'                 Equivalent to `#if defined (`name')'.
#ifndef `name'                Equivalent to `#if ! defined (`name')'.
#if #`predicate' (`answer')   Test if the assertion stated has been defined.
#if #`predicate'              Test if the assertion stated has been defined
                              with any answer.

  ---------------------------------
[THESE TRANSFORMATIONS ARE MADE ALWAYS]:-
  - All C comments are replaced with single spaces.
  - Backslash-Newline sequences are deleted, no matter where. This feature
lets you break long lines without changing their meaning.
  These two operations are done <before> proprocessor commands and macro names
are looked for.
  - Predefined macro names are replaced by their expansions.

  Notes:-
  ANSI Trigraphs are converted before Backslash-Newline is deleted.
  If a line ends in two or more backslashes, the last backslash and the
newline at the end of the line are dropped as usual.
  C comments and predefined macro names are not recognized inside a `#include'
command where the file name is delimited with `<' and `>'.
  C comments and predefined macro names are never recognized within a
character or string constant.
  A preprocessor command cannot contain newline, except for the
Backslash-Newline, or inside comments and strings and character constants.
  A preprocessor command name, and the `#' before it, cannot come from a macro
expansion.

  ---------------------------------
[HEADER FILES]
  The C preprocessor command `#include' reads in a file which is included in
the preprocessor's output. The usual convention is to give #include files
names that end with `.h'. It always treats the line after the `#include'
command as a separate line even if the #included file lacks a final newline.

  ---------------------------------
[FILES THAT YOU ONLY WANT TO BE INCLUDED ONCE]
  When one header file includes another, the standard way to avoid a header
file being included twice, causing compile errors etc, is to enclose the whole
file in a conditional, like this:

    #ifndef FILE_FOO_SEEN
    #define FILE_FOO_SEEN
    `the entire file'
    #endif /* FILE_FOO_SEEN */

  In a user header file, this macro name should not begin with `_'. In a
system header file, this name should begin with `__' to avoid conflicts with
user programs. The macro name should contain the name of the file and some
additional text, to avoid conflicts with other header files.
  If a header file proves to be contained entirely in a `#ifndef' conditional,
that run of the preprocessor will ignore any further #include's of that file.
  The command `#pragma once' is now obsolete and should not be used at all.
  The Objective C preprocessor command `#import' acts like `#include' but will
not include the same file again in the same preprocessor run. It is obsolete.

  ---------------------------------
[MACROS]
  In a macro:-
  - A simple macro is a macro without arguments.
  - If the body is missing, the macro is expands to null.
  - Newlines can only occur only inside comments and strings and character
constants, or in backspace-newline.
  - Parentheses need not balance. The body need not resemble valid C code.
(But the resulting output may cause compiler errors etc.)
  - Macro definitions do not apply to text met before the macro definition was
read.
  - Macro calls inside a macro definition, are expanded when the main macro is
expanded, not when it is defined.
  - If the macro has arguments, in the macro definition there must be no
spaces between the name and the `('.
  - ( ) in macro call arguments must balance, and a comma inside them does not
end a macro argument. But [ ] and { } need not balance, and they do not
prevent a comma from separating macro arguments. Thus, `macro (array[x = y, x
+ 1])' passes two arguments to `macro': `array[x = y' and `x + 1]', unless you
write it as `array[(x = y, x + 1)]', which is equivalent C code.
  - The macro call's arguments can contain other macro calls.
  - You may not define the same name as a simple macro and a macro with
arguments.
  - `#define foo()' is not the same as `#define foo'.
  - After `#define foo(x)', to call it with a null argument, you must write
`foo( )' with space between the parentheses.
  - Redefining a current macro causes a compiler warning, unless the new
definition means exactly the same as the old definition (e.g. when a header
file is read twice). To redefine a macro, undefine it first.
  ---------------------------------
[PREDEFINED MACROS]
  Several simple macros are predefined. You can use them without giving
definitions for them. There are standard macros and system-specific macros:-

  . . . . . . . . . . . . . . . . .
[STANDARD PREDEFINED MACROS]
  These are available with the same meanings whetever computer or operating
system is used. Their names all start and end with `__'. Those before
`__GNUC__' in this table are ANSI C standard; the rest are GNU C extensions.

__FILE__            The name of the current input file as a C string constant,
                    as in the `#include' or input file name argument.
__LINE__            The current input line number as a decimal integer
                    constant. Its definition changes with each new line of
                    source code.
  These two are useful in generating an error message to report an error
detected by the program, for example,
    fprintf (stderr, "Internal error: negative string length "
                     "%d at %s, line %d.", length, __FILE__, __LINE__);
__INCLUDE_LEVEL__   A decimal integer constant representing #include file
                    nesting depth. Incremented on every `#include' command and
                    decremented at every end of file. Zero for input files
                    specified by command line arguments.
 __DATE__           The date when the preprocessor was run, as an 11-character
                    string constant, like "Jan 29 1987" or "Apr  1 1995".
__TIME__            The time when the preprocessor was run, as an 8-character
                    string constant, like "23:59:01".
__STDC__            The constant 1, to say that this is ANSI Standard C.
                    (Whether that is actually true depends on what C compiler
                    will operate on the output from the preprocessor.)
__GNUC__            The major version number of GNU CC (`1' for GNU CC version
                    1, which is now obsolete, and `2' for version 2). Defined
                    if and only if this is GNU C and the entire GNU C compiler
                    is in use. Undefined you invoke the preprocessor directly.
__GNUG__            The GNU C compiler defines this when the compilation
                    language is C++.
__cplusplus         The GNU C compiler defines this when the compilation
                    language is C++. Formerly required by draft ANSI.
__STRICT_ANSI__     Defined if and only if `-ansi' was specified when GNU C
                    was invoked. Its definition is the null string.
__BASE_FILE__       The name of the main input file, as a C string constant.
                    This is the source file that was specified as an argument
                    when the C compiler was invoked.
__VERSION__         The version number of GNU C, as a string, which is usually
                    a sequence of decimal numbers separated by periods,
                    such as `"2.6.0"'.
__OPTIMIZE__        Defined in optimizing compilations.
__CHAR_UNSIGNED__   Defined if the data type `char' is unsigned on the target
                    machine. It is bad practice to use this macro yourself;
                    instead, use the standard macros defined in `limit.h'.

  . . . . . . . . . . . . . . . . .
[NONSTANDARD PREDEFINED MACROS]
  These macros vary according to the type of system and computer being used.
This manual, being for all systems and machines, cannot tell you exactly what
their names are; instead, we offer a list of some typical ones. You can use
`cpp -dM' to see the values of predefined macros.
  unix    normally predefined on all Unix systems.
  BSD     predefined on recent versions of Berkeley Unix (perhaps only in
          version 4.3).
          Other nonstandard predefined macros describe the kind of CPU, with
          more or less specificity. For example:-
  vax     predefined on Vax computers.
  mc68000 predefined on most computers whose CPU is a Motorola 68000, 68010
          or 68020.
  m68k    also predefined on most computers whose CPU is a 68000, 68010 or
          68020; however, some makers use `mc68000' and some use `m68k'. Some
          predefine both names. What happens in GNU C depends on the system
          you are using it on.
  M68020  has been observed to be predefined on some systems that use 68020
          CPUs---in addition to `mc68000' and `m68k', which are less specific.
  _AM29000
  _AM29K  Both predefined for the AMD 29000 CPU family.
  ns32000 predefined on computers which use the National Semiconductor 32000
          series CPU.
  Yet other nonstandard predefined macros describe the manufacturer of the
system. For example,
  sun     predefined on all models of Sun computers.
  pyr     predefined on all models of Pyramid computers.
  sequent is predefined on all models of Sequent computers.

  As these symbols' names do not start with `_', they are against the ANSI
standard, and the option `-ansi' stops them being defined. So, GNU C offers a
parallel series of symbols for this purpose, whose names are made from the
usual ones by adding `__' at the beginning and end. Thus, the symbol `__vax__'
would be available on a Vax, and so on. The set of nonstandard predefined
names in the GNU C preprocessor is controlled (when `cpp' is itself compiled)
by the macro `CPP_PREDEFINES', which should be a string containing `-D'
options, separated by spaces, e.g. on the Sun 3, we use this definition:
    #define CPP_PREDEFINES "-Dmc68000 -Dsun -Dunix -Dm68k"
 This macro is usually specified in `tm.h'.

  ---------------------------------
[STRINGIFICATION]
  Where a macro argument occurs in the macro's body, that occurrence of that
argument is stringified on expansion if it is preceded by a single `#'. That
is, it is turned into a string constant which would print out correctly as the
parameter including any contained strings etc, e.g. turning `foo ("z")' into
`"foo (\"z\")"'. For example, after:-
    #define WARN_IF(EXP) do { if (EXP) \
      fprintf (stderr, "Warning: " #EXP "\n"); } while (0)
  the call
    WARN_IF(going_critical)
  produces
    do { if (going_critical) \
      fprintf (stderr, "Warning: " "going_critical" "\n"); } while (0)
  which is treated the same as
    do { if (going_critical) \
      fprintf (stderr, "Warning: going_critical\n"); } while (0)

  Leading and trailing whitespace is ignored. Any sequence of whitespace
inside the parameter is converted to a single space in the stringified result.

  ---------------------------------
[CONCATENATION]
  When a macro body is expanded, the special operator `##' is deleted together
with all whitespace adjacent to it, for example, after:-
    #define COMMAND(NAME)  { #NAME, NAME ## _command }
  `COMMAND (quit)' and `COMMAND (help)' expand to `quit_command' and
`help_command'.
  - Comments are removed <before> the operator `##' is obeyed, so e.g. `/##*'
in a macro does not start a comment.

  ---------------------------------
[A NAME SUPPLIED BY MACRO EXPANSION CAN BE TREATED AS ANOTHER MACRO NAME]
e.g. after:
    #define double(x) (2*(x))
    #define call_with_1(x) x(1)
  `call_with_1 (double)' expands to `double(1)' amd then to `(2*(1))'.

  ---------------------------------
[BRACKET AND OPERATOR PRECEDENCE TROUBLE]
  If a macro body contains any sort of unbalanced bracket, that bracket's mate
is looked for (after the macro is expanded) in the rest of the line. This can
cause puzzling compilation faults and odd effects.
  The brackets around the arguments in the macro call do not survive in the
expanded text, and do not control which operators are obeyed first in it.
For example, after:         #define ceil_div(x, y) (x + y - 1) / y
  the text                  a = ceil_div (b & c, sizeof (int));
  expands into              a = (b & c + sizeof (int) - 1) / sizeof (int);
  which means               a = (b & (c + sizeof (int) - 1)) / sizeof (int);
  and not the intended      a = ((b & c) + sizeof (int) - 1) / sizeof (int);
  and the text              sizeof ceil_div(1,2)
  expands into              sizeof (1 + 2 - 1) / 2
  which means               (sizeof (1 + 2 - 1)) / 2
  and not the intended      sizeof ((1 + 2 - 1) / 2)
 For this reason, the macro should have been defined as:
    #define ceil_div(x, y)  (((x) + (y) - 1) / (y))

  ---------------------------------
[SWALLOWING THE SEMICOLON]
  When a macro's body is a compound statement:-    #define foo() {....}
  the obvious text            foo(); if(x==y) foo(); else puts("error");
  expands to                  {....}; if(x==y) {........}; else puts("error");
  and the compiler faults the surplus semicolon before the `else'.
  Writing instead             foo(); if(x==y) foo() else puts("error");
  cures it but looks odd. To expand `foo()' as a form that needs the calling
text to supply a semicolon after it, define it as:-
                              #define foo() do {....} while(0)

  ---------------------------------
[DUPLICATION OF SIDE EFFECTS]
  If a macro body mentions any of its arguments more than once. e.g.:-
    #define min(X, Y)  ((X) < (Y) ? (X) : (Y))
  and it is called with an argument that has a side effect or takes a long
time to run, e.g.    next = min (x + y, foo (z));
  it expands as:     next = ((x + y) < (foo (z)) ? (x + y) : (foo (z)));
  with foo() called twice (unless the compiler specially looks for `common
subexpressions'). This can be cured by defining `min' thus (using Gnu C
extensions):-
    #define min(X, Y) \
    ({ typeof (X) __x = (X), __y = (Y); (__x < __y) ? __x : __y; })
  or by calling it thus (if `foo()' returns the type `int'):-
    { int tem = foo (z); next = min (x + y, tem); }

  ---------------------------------
[SELF-REFERENTIAL MACROS]
  If a macro tries to call itself, at macro expansion expanding it stops there
and does not recurse infinitely, e.g. after:
  the text `foo' produces `foo (4 + foo)',
  and after      #define x (4 + y)
                 #define y (2 * x)
  the text `x' produces `(4 + (2 * x))'    and stays thus.

  ---------------------------------
[SEPARATE EXPANSION OF MACRO ARGUMENTS]
  Considering the order and effect of multiple scans for macro calls, as
affected by stringification and concatenation and stray unexpected commas.

  STRINGIFYING
  After        #define x (4 + x)
  the text     x (x (7))      is expanded from the inside out, and
  becomes      x (4 + 7)
  and then     x (4 + (4 + 7))
  as, if it had gone via `(4 + x (7))', expansion would have stopped here due
to the macro's name `x' occuring inside itself. The general rule is to expand
from the inside out.
  But after    #define str(s) #s
               #define foo 4
  the text     str
  becomes      "foo"
  and so remains, as "foo" is now in a string. The macro call `foo' is
expanded last, as it is stringified, although it is the innermost call.

  UNSHIELDED COMMA
  After               #define foo a,b
                      #define bar(x) lose(x)
                      #define lose(x) (1 + (x))
  the text            bar(foo)
  becomes             bar(a,b),  which is faulted "wrong number of arguments",
  and does not become lose(a,b)
  or the desired      (1 + (a,b))
  This case can be cured with brackets:-
    #define foo (a,b)
    #define bar(x) lose((x))
  The problem is more serious when the operands of the macro are not
expressions; for example, when they are statements. If the above example
had instead                       #define foo { int a, b; ... }
  the above cure would give       #define foo ({ int a, b; ... })
  which is allowed in Gnu C but not in ANSI standard C.
  Or reword to remove the comma that cause the trouble:-
                                  #define foo { int a; int b; ... }

  After       #define xstr(s) str(s)
              #define str(s) #s
              #define foo 4
  the text    xstr (foo)
  becomes     xstr (4)   (and not    str(foo)  )
  then        str (4)    (and not    "foo"     )
  then        "4"        (and not    "foo"     )
  Here the extra call level `xstr' is expanded after `foo', as it is the
outermost and its argument is not (directly) stringified. Thus, using an extra
macro level, an argument can be expanded and then stringified.

  ---------------------------------
[CASCADED USE OF MACROS]
  After:-    #define BUFSIZE 1020
             #define TABLESIZE BUFSIZE
             #undef BUFSIZE
             #define BUFSIZE 37
  the text   TABLESIZE
  becomes    BUFSIZE
  and then   37
  and not `1020', as by then `BUFSIZE' has been redefined. Macro calls in a
macro body are expanded when the main macro is expanded, not earlier.

  ---------------------------------
[NEWLINES IN MACRO ARGUMENTS; THEIR EFFECT ON ERROR MESSAGE LINE NUMBERS]
  After e.g.   #define twice(a) a, a
  the text     twice(x =
               y)
  becomes      x =
               y, x = y
  with the newlines in the arguments removed except in the first occurence of
each argument in the macro. This ensures that (unlike in many C's) the
expansion occupies the same amount of lines as the original, so that debug
message line numbers etc are not falsified. But if an argument that contains a
newline is never used, line numbers are wrong:-
  after       #define ignore_second_arg(a,b,c) a; c
  the text    ignore_second_arg (foo (),
              ignored (),
              syntax error);
  expands as  foo();
              syntax error
  and the line count is wrong by one.

  ---------------------------------
[C PREPROCESSOR OUTPUT]
  In the output from the preprocessor:-
  All preprocessor command lines have been replaced with blank lines and all
comments with spaces. A space is inserted after the expansions of most macro
calls. It will contain inserted lines of this form:-
    # `linenum' `filename' `flags'
 meaning that the next line originated in file `filename' at line `linenum'.
After the file name may come flags, which are `1', `2' or `3'. If there are
more than one, spaces separate them. Here is what the flags mean:
  1: start of a new file.
  2: return to a file (after having included another file).
  3: start of a system header file, so certain warnings should be suppressed.

  ---------------------------------
[TO CALL THE PREPROCESSOR DIRECTLY]
  (1) It expects up to two file names or minuses as arguments:-
cpp `infile' `outfile'     read from `infile', output to `outfile'
cpp `infile' -             read from `infile', output to standard output
cpp `infile'               read from `infile', output to standard output
cpp - `outfile'            read from standard input, output to `outfile'
cpp - -                    read from standard input, output to standard output
cpp -                      read from standard input, output to standard output
cpp                        read from standard input, output to standard output

  (2) It has these extra options which you can't call directly via gcc:-
-lang-c++  makes the preprocessor handle C++ comment syntax, and includes
           extra default #include directories for C++
-lang-objc enables the Objective C `#import' command.
-lang-c    explicitly turns off both of these extensions.
-lang-objc++ enables both.
-lint      Look for commands to the program checker `lint' embedded in
           comments, and emit them preceded by `#pragma lint'. For example,
           `/* NOTREACHED */' becomes `#pragma lint NOTREACHED'.
-$         Forbid use of `$' in identifiers. `gcc' sends this option to the
           preprocessor (`gpp') if you specify `-ansi'.

  ---------------------------------

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019