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

TRM900@psuvm.psu.edu (Tony R. Marasco) (12/02/90)

Is there any software available to translate ANSI C to non-ANSI C?  I heard
it could be done using yacc, but I'm not familiar enough with ANSI-C or
yacc to attempt this.  Any help is appreciated.

Thanks,
-------
| Tony Marasco                 |  "Questions are a burden for others.     |
| Penn State University        |   Answers are a prison for oneself."     |
| Schuylkill Haven, PA 17976   |     - The Prisoner                       |
| trm900@psuvm.psu.edu       - or -   %s!psuvax1!psuvm.BITNET!trm900      |

lsalomo@hubcap.clemson.edu (lsalomo) (12/02/90)

Help!

I'm trying to define a typedef for a function pointer which takes an integer
for a parm.

typedef (void *pfn)(int);

I'm using gcc, which gives a parse error.  Of course, I should ask this in
one of the gcc newsgroups, but I'm thinking it is the way the line is written.

Can anyone help (and ASAP!  I'm working on a compiler project!)

Cheers,
Q - the "Q"uestor for knowledge (, a degree, etc.)

lsalomo@hubcap.clemson.edu
ibmman@clemson.clemson.edu
=============================================================================
"Gee Wally, I think there's something wrong with the Beaver."
=============================================================================

lsalomo@hubcap.clemson.edu (lsalomo) (12/02/90)

From article <12000@hubcap.clemson.edu>, by lsalomo@hubcap.clemson.edu (lsalomo):
> Help!
> 
> I'm trying to define a typedef for a function pointer which takes an integer
> for a parm.
> 
> typedef (void *pfn)(int);

It should be 

typedef void (*pfn)(int);

Thanks to those who responded!

Cheers,
Q - the "Q"uestor for knowledge (, a degree, etc.)

lsalomo@hubcap.clemson.edu
ibmman@clemson.clemson.edu
=============================================================================
"Gee Wally, I think there's something wrong with the Beaver."
=============================================================================

gwyn@smoke.brl.mil (Doug Gwyn) (12/02/90)

In article <90335.163132TRM900@psuvm.psu.edu> TRM900@psuvm.psu.edu (Tony R. Marasco) writes:
>Is there any software available to translate ANSI C to non-ANSI C?

Yeah, stick a semicolon after every thirtieth source character.

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?

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.

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

In article <2880@lupine.NCD.COM> rfg@NCD.COM (Ron Guilmette) writes:
> This is indeed a problem which currently unprotoize doesn't not solve.
> However I do not think that unprotoize *should* solve it.

I don't know what the name of the tool to solve it should be, but I think
that such a tool would really help spread ANSI C. As it is, ANSI C programs
are just plain incompatible with pre-ANSI compilers, and simply stripping
off the prototypes does not solve that problem. I appreciate the work you've
done, though I won't be likely to benefit from it... GCC doesn't like little
machines like the ones I use.

> 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).

Both of these are reasonable assumptions outside the world of VAX-class
machines. In addition, this particular problem is my #1 headache converting
such code to run on small computers. Floating point problems are relatively
uncommon, since code that's broken in the first place isn't as likely
to show up in a source distribution as non-portable code.
-- 
Peter da Silva.   `-_-'
+1 713 274 5180.   'U`
peter@ferranti.com 

amodeo@dataco.UUCP (Roy Amodeo) (12/05/90)

In article <2880@lupine.NCD.COM> rfg@NCD.COM (Ron Guilmette) writes:
>
>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.

The cross-compiler we bought for our development work does this. When you
first kick this in, people grumble and complain loudly. They eventually
add casts to make the noise go away. And sometimes they find that they
had arguments in the wrong order or that they were feeding a routine
the wrong data. I would suggest that if you do put in this warning,
make it the default. If you *must*, allow a user to turn it off with a
command line option. This kind of thing goes well with warnings about
calling functions with no prototypes. But then, I'm the weak-memoried
type that strong typing was meant for.

>Here is a better example of the problem:
>
>		extern f (double);
>
>		... f (3); ...
>
I don't suppose you can say
		3d or 3.0L
for
		(double)3
can you? That would be a little less obnoxious.

rba iv	- a foolish signature is the hobgoblin of little minds
nrcaer!dataco!amodeo

chip@tct.uucp (Chip Salzenberg) (12/05/90)

According to rfg@NCD.COM (Ron Guilmette):
>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.

Such a warning is too lax.  You need warnings wherever a parameter
value, after default promotions of char->int, short->int,
float->double, etc., is not of the *exact* same type as the prototyped
parameter.

I would make two exceptions to the above rule.  Character pointers
and void pointers are guaranteed by the standard always to have the
same representation, so we can consider them to be equivalent for
purposes of parameter passing.  A similar guarantee exists about the
signed and unsigned variants of integral types, so they also may be
considered identical.

As an example, one machine (VAX) provides int and long types with the
same representation, whereas the next machine ('286 large model) does
not.  Passing "0" for a long parameter thus will require a "(long)"
cast for complete equivalence without prototypes, no matter which
machine you happen to be using to run GCC.

If the aim is to provide prototype-free code that works just like the
prototyped code, then the warning must be based on portability, not a
particular machine's data representation.
-- 
Chip Salzenberg at Teltronics/TCT     <chip@tct.uucp>, <uunet!pdn!tct!chip>
      "I'm really sorry I feel this need to insult some people..."
            -- John F. Haugh II    (He thinks HE'S sorry?)

darcy@druid.uucp (D'Arcy J.M. Cain) (12/06/90)

In article <308@dcsun21.dataco.UUCP> Roy Amodeo,DC writes:
>In article <2880@lupine.NCD.COM> rfg@NCD.COM (Ron Guilmette) writes:
>>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.
> [...]
>the wrong data. I would suggest that if you do put in this warning,
>make it the default. If you *must*, allow a user to turn it off with a
>command line option. This kind of thing goes well with warnings about

Please don't.  At least make it a compile time option.  I happen to like
the idea of not having to put casts everywhere.  It adds a level of data
abstraction that I think is desireable.  If a header changes a data type
let the compiler worry about changing the call.

-- 
D'Arcy J.M. Cain (darcy@druid)     |
D'Arcy Cain Consulting             |   There's no government
West Hill, Ontario, Canada         |   like no government!
+1 416 281 6094                    |

karl@ima.isc.com (Karl Heuer) (12/09/90)

In article <308@dcsun21.dataco.UUCP> amodeo@dcsun03 (Roy Amodeo,DC) writes:
>In article <2880@lupine.NCD.COM> rfg@NCD.COM (Ron Guilmette) writes:
>>[I've been planning to add an (optional) GCC warning for non-trivial
>>conversions caused by prototypes.]

I like this solution.  (Note that it may be approximated with current tools by
unprotoizing and then running lint.)

>make it the default [with an option to turn it off].

The important bit is to get the feature implemented and make it optional.
Deciding which setting should be default is a minor issue, and in any case it
can be tuned for your local site.  (I usually run gcc with -Wall -Wcast-qual
-Wwrite-strings, myself.)

>I don't suppose you can say "3d" or "3.0L" for "(double)3" can you?

Since floating-point constants have type "double" by default, it suffices to
use "3.0" (or even "3.", but I consider it good style to always have a digit
on each side of the decimal point).

Karl W. Z. Heuer (karl@ima.isc.com or uunet!ima!karl), The Walking Lint