[comp.lang.c++] SUMMARY: C and C++

gwu@nujoizey.tcs.com (George Wu) (04/04/91)

In article <1991Apr3.011032.14110@terminator.cc.umich.edu>,
normanb@pinhead.citi.umich.edu (David R. Richardson) writes:
|> Last week I asked this newsgroup for comments on combining C and
|> C++.  Here is a summary of replies:
|> 
|> [ . . . stuff deleted . . . ]
|> 
|> For example, cfront performs this initialization by calling a routine,
|> "_main()".  In translating your C++ code, cfront places a call to this
|> routine right after YOUR main().

     Correction: _main() is called *before* my/your main().  And to be
entirely complete, cleanup code (destructors for static and global objects)
need to be called when main() is finished.

|> [ . . . more deletions . . . ]
|> 
|> Solutions?  There are two general ways around this (neither one of
|> which is very elegant).

     Still another solution is to write your C main() routine as normal,
but explicitly call _main() from it:

int main(int argc, char *argv[])
{

#ifdef __cfront

	extern int _main();

	_main();

#endif

	// rest of ordinary C main() code
}

Just be sure to link with the C++ compiler and libC, as several compilers
generate additional information at the final link stage.

|> This still leaves some problems.  What if you want to write a general
|> library of routines in C++ that anyone can use?  Then that user will
|> have to write a dummy C++ main() which calls HER main() which then calls
|> YOUR library?  Yuck!  It seems like there should be a better way...

     Well, if your C++ routines are strictly routines, ie. not member
functions of a class, you can declare them to use C linkage:

extern "C" void func();

void func()
{
	// . . .
}

     Of course, this rather restricts what you can do in the C++ library,
for instance C linkage implies no parameter overloading.  (You couldn't
make use of overloading anyways, since your calls would be from a C
compiler, which has no concept of overloading.)

     Another approach might be to define some macros to make writing the
C wrapper functions easier:

C::func()
{
	// . . . 
}

#define Wrap(className,methodName) \
name2(Wrapper,name2(className,className))(void *object) \
{ \
	((className *)object)->methodName(); \
}

where name2(x,y) is converted by the cpp into xy (see generic.h, if you've
got it).  Your C++ method is then callable from C code like this:

// assume there's a class Class, with method Function

extern WrapperClassFunction(void *object);

int
func(void *object)
{
	// . . .
	WrapperClassFunction(object);
	// . . .
}

     Note that this can still get pretty messy, since you may have to allow
for overloading, parameters, etc.


							George


----
George J Wu, Software Engineer        | gwu@tcs.com or uunet!tcs!gwu
Teknekron Communications Systems, Inc.| (415) 649-3752
2121 Allston Way, Berkeley, CA, 94704 | Quit reading news.  Get back to work.

billri@redwood.sos.ivy.isc.com (Bill Rizzi) (04/05/91)

In article <1990@godzilla.tcs.com>, gwu@nujoizey.tcs.com (George Wu) writes:
|> In article <1991Apr3.011032.14110@terminator.cc.umich.edu>,
|> normanb@pinhead.citi.umich.edu (David R. Richardson) writes:
|> |> Last week I asked this newsgroup for comments on combining C and
|> |> C++.  Here is a summary of replies:
|> |> 
|> |> [ . . . stuff deleted . . . ]
|> |> 
|> |> For example, cfront performs this initialization by calling a routine,
|> |> "_main()".  In translating your C++ code, cfront places a call to this
|> |> routine right after YOUR main().
|> 
|>      Correction: _main() is called *before* my/your main().  And to be
|> entirely complete, cleanup code (destructors for static and global objects)
|> need to be called when main() is finished.

	Actually, cfront (AT&T C++ 2.1) places the call to _main() as the
first statement in the definition of C function main().  Just take a peek at
the generated C code.  You'll see something like:

... main(...) { _main();
...
}

	I don't know for sure that _main() is standard with all C++
compilers, however.

	Regarding destructors, the C++ library has an exit() function which
takes care of this.  So as you pointed out, it is important to link with the
C++ libraries.	If your main() function is in C, an (early) call to _main() is
indeed appropriate.  It is probably also a good idea to call exit() explicitly,
rather than "falling off" the end of your main() function and relying on the C
runtime to call exit().


	Bill

-- 
Bill Rizzi		INTERACTIVE Systems Corporation
billri@ivy.isc.com	26635 W. Agoura Rd, Suite 200
818-880-1200 x2110	Calabasas, CA  91302

steve@taumet.com (Stephen Clamage) (04/06/91)

billri@redwood.sos.ivy.isc.com (Bill Rizzi) writes:

>	Actually, cfront (AT&T C++ 2.1) places the call to _main() as the
>first statement in the definition of C function main().  Just take a peek at
>the generated C code.  You'll see something like:

>... main(...) { _main(); ...  }

>	I don't know for sure that _main() is standard with all C++
>compilers, however.

Different C++ compilers have different solutions for this.  Some call
a function equivalent to _main() but with a different name.  Some use
other means to achieve runtime initialization of static data.

The ANSI C++ committee is addressing possible ways to standardize the
static constructor/destructor problem in multilanguage environments.
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com