[comp.std.c] ANSI C -> non-ANSI C

peter@ficc.ferranti.com (Peter da Silva) (12/02/90)

[ cross-posted to comp.std.c, because a tool like this would do more to speed
  the conversion of software to ANSI than all the debate in the world. Perhaps
  someone on the committee could do it in their copious spare time... :-> ]

> >Is there any software available to translate ANSI C to non-ANSI C?

> More seriously, you should be more specific about the problem
> that you think you're trying to solve.  Is it to eliminate
> parameters from prototypes in function declarations, or is it
> something more difficult?

I'd like some software to convert new- to old- style declarations myself.
None of the deproto tools I've seen so far do an adequate job, because
while they clean up the prototypes they don't clean up all the calls. For
example, if you want to run ANSI C through a K&R compiler, you need to change:

	int foo(char *, char *, int);
	char bazbuffer[BUFSIZ];

	foo(NULL, bazbuffer, 69);

Into:

	int foo();

	foo((char *)0, bazbuffer, 69);

Just removing the prototypes isn't enough. To do this right you pretty much
need a complete codewalker, so it might be cheaper just to go out and get a
new compiler. Unfortunately, sometimes one isn't available, and ignoring the
older systems is just going to ensure that islands of pre-ANSI C live forever
in dusty decks, waiting to catch the unwary.

Also, this hypothetical tool *would* just have to be written once. It doesn't
have any reason to do any machine-dependent stuff.
-- 
Peter da Silva.   `-_-'
+1 713 274 5180.   'U`
peter@ferranti.com 

rfg@NCD.COM (Ron Guilmette) (12/03/90)

In article <Z.Y7HU9@xds13.ferranti.com> peter@ficc.ferranti.com (Peter da Silva) writes:
+[ cross-posted to comp.std.c, because a tool like this would do more to speed
+  the conversion of software to ANSI than all the debate in the world. Perhaps
+  someone on the committee could do it in their copious spare time... :-> ]
...
+I'd like some software to convert new- to old- style declarations myself.
+None of the deproto tools I've seen so far do an adequate job, because
+while they clean up the prototypes they don't clean up all the calls. For
+example, if you want to run ANSI C through a K&R compiler, you need to change:
+
+	int foo(char *, char *, int);
+	char bazbuffer[BUFSIZ];
+
+	foo(NULL, bazbuffer, 69);
+
+Into:
+
+	int foo();
+
+	foo((char *)0, bazbuffer, 69);
+
+Just removing the prototypes isn't enough. To do this right you pretty much
+need a complete codewalker, so it might be cheaper just to go out and get a
+new compiler. Unfortunately, sometimes one isn't available, and ignoring the
+older systems is just going to ensure that islands of pre-ANSI C live forever
+in dusty decks, waiting to catch the unwary.

As the person who built protoize and unprotoize I guess I can comment. :-)

This is indeed a problem which currently unprotoize doesn't not solve.
However I do not think that unprotoize *should* solve it.

Let me explain.

Unprotoize just does all of the necessary editing to convert ANSI-C with
prototypes into ANSI-C without prototypes.

To solve the problem problem described above you need a different tool
I think.

What I have always planned on doing (if I ever get the time) is to simply
add another (optional) warning to GCC which would warn you about all
actual parameters to (prototyped) functions which get an implicit change
of representation by virtue of being passed into a formal parameter of
a sufficiently different type to require such a change of representation.
Then the programmer could edit his/her own code (adding explicit type
casts as necessary) until all of these warnings went away.  At that point,
unprotoization could be done safely.

Adding such a warning to GCC would take less than a day (for any experienced
GNU hacker).

By the way... the above example is not really a very good one because it
seems to assume that NULL is defined to plain `0' and (more importantly)
because it assumes that ((int) 0) and ((char *) 0) have different
representations (which they do not on any of the machines that I work on).

Here is a better example of the problem:

		extern f (double);

		... f (3); ...

Here, when f is prototyped, you get an implicit change of representation
of the actual argument (3) to the (prototype-supplied) type of the formal
argument.  The result is that the called function receives a value of type
double with the value 3.0.

As soon as you remove the prototype from f() however, the implicit type
conversion effect disappears also.  Chaos will then ensue.

-- 

// Ron Guilmette  -  C++ Entomologist
// Internet: rfg@ncd.com      uucp: ...uunet!lupine!rfg
// Motto:  If it sticks, force it.  If it breaks, it needed replacing anyway.