mcg@omepd (Steven McGeady) (05/11/87)
Apropos of the recent discussions regarding 'inline' functions in C and
C++, I have written a preprocessor that accepts C programs with the C++
style 'inline' storage class and produces as output a functionally
equivalent program with the functions so marked expanded in the places
where they are called. The manual page for the program is included
below, at the end of this message. I am planning on distributing this
to comp.sources.unix soon, but would like to beta-test the program at
a few sights first, to shake out any latent portability problems.
Ideal beta-testers are persons who:
1) Have machines other than VAXen;
2) Know C, and are capable of porting large and/or complex programs;
3) Have honest needs for or interests in the inline substituter, and
are likely to use it;
4) Have the time and energy to install the program and shake it out
over the next few weeks.
The program is about 4000 lines of fairly complex C (think of the source to
'c2', but with comments), but it is hoped that there are few, if any, machine
or system dependencies. The program has been extensively tested on the VAX,
with 'normal' C programs (whatever that means).
Please respond to me at the address below. Queries about the program
are welcome, and are best directed to me personally, rather than the net.
S. McGeady
(503) 696-4393 (w)
(503) 235-2462 (h)
mcg@omepd.intel.com
...!intelca!mipos3!omepd!mcg
...!tektronix!ogcvax!omepd!mcg
============================================================================
INLINE(1) UNIX Programmer's Manual INLINE(1)
NAME
inline - C preprocessor for inline functions
SYNOPSIS
inline [-w] [-e] [-s] [-n] [-d] [-S[em]] [infile] [outfile]
DESCRIPTION
_I_n_l_i_n_e is a preprocessor that accepts C language programs
containing the additional storage-class keyword inline
applied to function declarations, and generates identical C
programs that (usually) have the functions so marked
expanded where they are called. Input code lacking the
inline keyword is output unchanged. Thus _i_n_l_i_n_e allows C
programmers a feature similar to that provided by the C++
language. However, while the specifications are the same,
the _i_n_l_i_n_e program works substantially differently from
currently implemented C++ compilers. Current C++ compilers
rewrite inline functions into expressions, thus prohibiting
loops in them, but allowing their use in contexts such as
control statements of looping constructs. _I_n_l_i_n_e normally
reformats inline functions into code concealed in local
blocks, adds variables for parameter and return values, and
changes return statements into gotos. This allows use of
all normal C constructs within inlines. This rewriting is
appropriate in all contexts except when inline functions are
called in the control parts of for and while loops, and in a
few other cases. In these cases, the C++ style expansion is
used, and the procedures are rewritten as expressions when
possible (that is, when they lack loops, switches, and
goto's).
_I_n_l_i_n_e emits extern (or, optionally, static) predeclarations
for inline functions, so that unexpanded instances are com-
piled correctly, and can be supplied externally. Addition-
ally, options are provided to emit the bodies of any unex-
panded functions as static procedures at the end of a
module, or to emit the bodies of all inline functions alone,
allowing inline functions to be collected into a library.
The following options are provided:
-w supress warning messages about unexpandable instances
of inline functions.
-e emit predeclarations as externs. Do not dump bodies of
unexpanded functions.
-s emit predeclarations as statics. Dump bodies of unex-
panded functions.
-n emit no predeclarations at all, and do not dump bodies
of unexpanded functions. This allows the gathering of
inline functions into a library, to resolve unexpanded
references and any instances where the address of an
inline was taken.
-d do not emit the main program, only dump the bodies of
all inlines.
-S emit (on the standard error output) statistics about
the expansion process.
-Se emit extended statistics, giving expansion statistics
for each inline.
-Sm emit statistics about the memory usage of the program
(if the program is compiled to collect these statis-
tics).
If no input file is specified, the standard input is
assumed, and likewise for the standard output.
BUGS/CAVEATS
_I_n_l_i_n_e does not perform predictably when given incorrect C
programs. It is easy to test a program that contains
inlines with the command:
cc -c -Dinline=static file.c
When multiple inline functions are present in a single
expression, the order in which the functions are executed in
the inline code is sometimes different from the order in
which they would have been called had they not been
expanded. In particular, all functions in the expression
will be evaluated, left-to-right, before the operations in
the expression are performed. This is correct for most C
operators, _e_x_c_e_p_t the comma, boolean-or (||), and boolean-
and (&&) operators. Inline handles all but the comma opera-
tor correctly, expressionizing calls on the right side of
the conditional operators.
While _i_n_l_i_n_e attempts to pass preprocessor defines through
without change, it is strongly suggested that _i_n_l_i_n_e be exe-
cuted on code that has already been processed by the C
preprocessor /lib/cpp.
_I_n_l_i_n_e does not recognize certain degenerate cases of func-
tion declarations and calls, in particular:
(foo)(arg);
SEE ALSO
cc(1), cpp(1)
NOTE
_I_n_l_i_n_e source code is Copyright, 1986, 1987 by S. McGeady,
all rights reserved.
AUTHOR
S. McGeady
3714 SE 26th Ave.
Portland, OR 97202
(503) 235-2462
====================================================== predec ( ( rougDes of