🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.g++.help
Article #838

Re: Problems #including K&R function prot

#838
From: Steve Clamage
Date: Mon, 27 Nov 1995 23:29
75 lines
3332 bytes
In article kev@NNTP.MsState.Edu, shekar@gizmo.cs.msstate.edu (Shekar Ramanathan) writes:
>>
>What you should do is have another file called foo.c and compile it using
>a K&R C compiler.  In main.C, you should just include a prototype declaration
>for foo and finally link them together.

That is basically correct, with a warning below.

>foo.c
>int foo(boo)
>    int boo;
>{
>   return boo;   
>}
>
>main.C:
>
>extern "C"{
>	int foo();

I don't know if the above declaration is a typo or a misunderstanding. See below.

>}
>int main()
>{ cout << foo(0) << endl; }

Using 'extern "C"' doesn't eliminate the need for a full prototype. The
declaration
	int foo(); // in any context
in C++ is always taken to mean a function foo which has no parameters.
You cannot call foo with any arguments. You have to declare it the
way it is defined and used:
	int foo(int);
(Perhaps this error was just a typo, but it is also a common misunderstanding.)

The warning about mixing K&R C programs with C++ concerns functions
which take "narrow" arguments, like char, short, or float.

In K&R C (and Standard C when you don't use prototypes), you might write
a function like this:
	int f() char k; { .... } /* old-style C function definition */
and provide a declaration like this:
	int f(); /* C declaration */

The C compiler might see only the declaration of f, and have no way of
knowing what sort of parameter is expected. Consequently, when you call
f, any argument of type char, enum, or short will be promoted to type int:
	char c;
	short s;
	f(c); /* treated in C as though you wrote f((int)c) */
	f(s); /* treated in C as though you wrote f((int)s) */
Inside function f, the compiler generates code that assumes an int
is passed, and converts it to a char for use inside the function
when you mention parameter k.

In Standard C or in C++, a prototype specifies the argument type expected.
If you write
	int f(char);
and call f with an argument of any type, the value will be converted to
type char and passed to f. Notice this prototype does NOT match the way
the K&R C function works. It expects an int to have been passed, and if
a char is passed, it might not work correctly. On some systems you will
get the desired result by accident; on others you get trash. It depends
on the byte order of the system and the way in which arguments are passed.

If you must call K&R C functions from C++ (or from Standard C modules
using prototypes) it is best if the K&R C functions have parameters
of only those types which do not undergo promotion: signed/unsigned
int, signed/unsigned long, and double among the arithmetic types.

Otherwise, if the K&R function is defined to take a char, enum, or short,
the prototype should specify int. If the function is defined to take a
float, the prototype should specify double.
---
Steve Clamage, stephen.clamage@eng.sun.com
Technical Details
Message-ID: <49dhkf$j1e@engnews1.eng.sun.com>
Path: arc1-ca.pugleaf.net!engnews1.Eng.Sun.COM!usenet
References: <49da94$kev@NNTP.MsState.Edu>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!engnews1.Eng.Sun.COM!usenet
From: clamage@Eng.Sun.COM (Steve Clamage)
Newsgroups: gnu.g++.help,comp.lang.c++
Subject: Re: Problems #including K&R function prot
Date: 27 Nov 1995 23:29:19 GMT
Organization: Sun Microsystems Inc.
Message-ID: <49dhkf$j1e@engnews1.eng.sun.com>
References: <49da94$kev@NNTP.MsState.Edu>
Reply-To: clamage@Eng.Sun.COM
NNTP-Posting-Host: taumet.eng.sun.com