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