[comp.lang.c] Converting ANSI-C to non-ANSI-C, Please help.

morten@modulex.dk (Morten Hastrup) (02/08/91)

Does anyone outthere have/know of any tool(converter) capable
of converting ANSI-C to non-ANSI. Ex.:

	return_type function(type1 arg1)
	{
	   .... /* something is going on */
	}

	is converted into:

	#ifdef __STDC__ /* or something other than __STDC__ */
	return_type function(type1 arg1)
	#else
	return_type function(arg1)
	type1 arg1;
	#endif
	{
	   .... /* something is going on */
	}

My problem is that our sun doesn't have any ANSI compiler.

Please help me.

Morten

------------------------------------------------
A/S MODULEX		Phone: (+45) 44 53 30 11
Lyskaer 15		Fax:   (+45) 44 53 30 74
DK-2730 Herlev
Denmark
Morten Hastrup		Email: morten@modulex.dk
------------------------------------------------

rfg@lupine.ncd.com (Ron Guilmette) (02/11/91)

In article <712@modulex.dk> morten@modulex.dk (Morten Hastrup) writes:
+Does anyone out there have/know of any tool(converter) capable
+of converting ANSI-C to non-ANSI. Ex.:

Yes.  I have built a pair of tools called protoize & unprotoize.  A new
version of these is now being pre-tested.  If you have a burning desire
to get your hands on the latest versions of these tools, and if you
know how to build & install the GNU C compiler (GCC) and if you have
access to the Internet (so that you can do anonymous FTP's) please
contact me by E-mail, tell me what you plan to use these tools for,
and I may make you a pre-tester for the new version.

+	return_type function(type1 arg1)
+	{
+	   .... /* something is going on */
+	}
+
+  is converted into:
+
+	#ifdef __STDC__ /* or something other than __STDC__ */
+	return_type function(type1 arg1)
+	#else
+	return_type function(arg1)
+	type1 arg1;
+	#endif
+	{
+	   .... /* something is going on */
+	}
+
+My problem is that our sun doesn't have any ANSI compiler.

There is a simple solution to that problem.  Get GNU!  Its free.

By the way, your example makes me want to comment (... well... vomit
actually).

One thing that I have tried to stress to all users of protoize & unprotoize
is that putting all of those #ifdef __STDC__ directives into your code is
dumb, stupid, ugly, and unnecessary, and that it actually *degrades* (by
a significant amount) the "quality" of your code.

It would be much better to simply maintain one single version of your code
(all in prototype form of course) and then to use my unprotoize tool to
unprotoize it on the fly (perhaps via commands in your Makefile) when you
need an unprotoized version.  That way, you won't end up with code that
contains two different "function headers" for each function.  Anytime you
have such a pair, you have to worry that they may diverge (over time) due
to maintenance activities, and thus become inconsistant with one another.
Also, if you avoid code which looks like the code in the latter part of your
example, you won't end up with code that protoize and unprotoize can no
longer process effectively (due to the rampant and excessive use of
preprocessing directives).

guido@cwi.nl (Guido van Rossum) (02/11/91)

rfg@lupine.ncd.com (Ron Guilmette) writes:

>One thing that I have tried to stress to all users of protoize & unprotoize
>is that putting all of those #ifdef __STDC__ directives into your code is
>dumb, stupid, ugly, and unnecessary, and that it actually *degrades* (by
>a significant amount) the "quality" of your code.

Suppose I don't want to use unprotoize on the fly (don't ask me why,
maybe I'm just stubborn, maybe I develop part of my code that has
neither a Standard C compiler nor enough power to run unprotoize on
the fly (could it be a Mac?)).  What's the best thing to do?  I
think it's this; comments are welcome.  I use cpp to hide the
prototypes from the Classic C compilers as follows:

     #ifdef __STDC__
     #define PROTO(x) x
     #else
     #define PROTO(x) ()
     #endif

This is used like this in header files (you'll get used to the the
double parentheses very quickly).

     extern char *foo PROTO((int, double *, char **));

The Classic C compiler sees foo() while the Standard compiler sees
foo(int, double *, char **).

It is also usable in source files, provided you only use argument
types that don't need widening (so no chars, shorts or floats):

      char *foo PROTO((int, double *, char **));
      foo(size, result, list)
		int size;
		double *result;
		char **list;
      {
      	...
      }

Standard C compilers are required to accept this.  It is less ugly
than the solution with #ifdef __STDC__ at each function header, and
also keeps the two versions from diverging: every time you compile
with a Standard C compiler it will check correspondence between the
prototype and the classic header.

--
Guido van Rossum, CWI, Amsterdam <guido@cwi.nl>