[comp.lang.c] C to C++ Converter

ts@ztivax.UUCP (Thomas Schreiber) (08/21/89)

Is there anybody who has/knows about a tool that converts
a C source so that the C++-translator accepts it without
producing unnecessary warnings ?

I need this C-to-C++-Converter primarily for type-checking
old C code.

If I can't find such a tool, I'll think about writing one
by myself. Who else needs a tool like this ?

Please let me know !

Thomas Schreiber              e-mail: ts@ztivax.siemens.com
K PN SE 21, Siemens AG
Munich, Germany

rfg@dg-rtp.dg.com (Ron Guilmette) (08/22/89)

In article <728@ztivax.UUCP> ts@ztivax.UUCP (Thomas Schreiber) writes:
>
>Is there anybody who has/knows about a tool that converts
>a C source so that the C++-translator accepts it without
>producing unnecessary warnings ?
>
>I need this C-to-C++-Converter primarily for type-checking
>old C code.
>
>If I can't find such a tool, I'll think about writing one
>by myself. Who else needs a tool like this ?

I have created a tool which does the bulk of the conversion
automatically.  It is publically available (FSF copylefted).
It still needs some work, but it may be useful to you in its
current form.  (More info about obtaining this tool is given
below.)

There are LOTS of little nit-picky issues which come up when
converting old C code to C++ code.  I will not go into *all* of the
details here, other that to suggest that you try a large conversion
yourself and see where the problems are.

The *main* issue seems to be conversion of function declarations
and definitions to ANSI-C/C++ prototype form.  This is what my tool
does.

I tried a large conversion (i.e. GCC in C => GCC in C++) and found
that the following additional things (among others) were problems.

1)	Protoization of function declarations/definitions may force
	you to re-order your "type" declarations (i.e. struct/union/enum
	type definitions) such that they appear earlier in your files.
	For example, the following will have to be reordered following
	protoization:

		extern void glop ();

		struct phoo { int splat; int blah; };

		void glop (arg)
		    struct phoo arg;
		{
			/* body */
		}

	After (full) protoization, the first declaration of glop()
	will look like:

		extern int glop (struct phoo arg);

	This will cause errors unless the declaration of "struct phoo"
	is moved up to a point before the first declaration of glop().

2)	Old-style "varargs" functions need to be converted to use
	the new ANSI-C/C++ "stdarg" conventions & declarations.

3)	The following code is perfectly legal C code, but becomes illegal
	C++ code after protoization.  Can you guess why?  It will still be
	legal C code after protoization, but it will get a warning (quite
	rightly so) from GCC after protoization.  G++ on the other hand will
	not like it at all after protoization.

		enum color { red, green, blue };

		extern void splat ();

		void nasty ()
		{
			splat(0);
		}

		void splat (arg)
		    enum color arg;
		{
			/* body */
		}

Even though the above problems are irritating during the conversion
process, it is "good" that you take the time to make the necessary
adjustments.  Doing a good conversion job insures that your code
will be more portable when the inevitable deluge of ANSI-C compilers
arrives on the scene.  (Soon, I hope.)  Further, if you do a complete
protoization/conversion, you are likely to find many function-calling
errors (wrong number/order/type of actual arguments) in your code.
Having your (ANSI-C) compiler find these errors for you what strong
type checking is all about!  (I found several errors in the GCC sources
this way.)

My "protoize" tool works in two phases.  First, you run a modified
version of the GNU C compiler (i.e. GCC) over the code to be converted.
In this phase, GCC writes out files of prototyping information to be
used later during the actual conversion.  Second, you run the "protoize"
program.  This program reads all of the prototype-info files created in
step (1) and performs the necessary edits to *all* of your source files
(both "base" and "include" files).  That is all there is to it.

The required patches to GCC, and the protoize program itself are all
combined into one "patch file" for GCC (1.35).  This file is called
protoize-1.01.Z and may be obtained via anonymous FTP from yahi.stanford.edu
(36.83.0.92).  There is also a 1.00 and a 1.02 version out there, but
these are both slightly broken.  I suggest using 1.01 for now, until
I get time to make a new version.  There is a lengthy man page included
in the "patch file".  Read it.

P.S.  Typedef'ed type names are not handled correctly yet.  Real Soon Now.

// Ron Guilmette