Topic: Calling C++ from C
Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: Wed, 1 Nov 2000 19:10:57 GMT Raw View
In article <1ejdcne.1gu00pvkg4nuoN%jthill@telus.net>, jthill@telus.net
(Jim Hill) wrote:
>> I have [as a] given:
>> pascal short main(CWPluginContext context);
>
>What should the C++ standard say about this? It doesn't even pretend to
>be standard C++.
>
>If the declaration were `extern "Pascal" short plugin` one could argue
>that the implementation permits `plugin` to be written in standard C++,
>and so must meet the standard's requirements.
I recall the example above is a makeshift implementation made the compiler
in C, in view that C does not have an "extern "<name>"..." construct.
(Which was made because the OS is written in Pascal, so it is not possible
to interface with the OS without being able to call functions with Pascal
linkage.)
So C++ has nothing to say about it.
Hans Aberg * Anti-spam: remove "remove." from email address.
* Email: Hans Aberg <remove.haberg@member.ams.org>
* Home Page: <http://www.matematik.su.se/~haberg/>
* AMS member listing: <http://www.ams.org/cml/>
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: Tue, 31 Oct 2000 19:54:36 GMT Raw View
In article <39FE363D.F162D7F8@wizard.net>, James Kuyper
<kuyper@wizard.net> wrote:
>> >To specify details of support for languages other than C would
>> >require the C++ standard to track other language standards.
>> No, this is not really needed: All that is needed is describing how C++
>> should behave when called from another language. In addition one could add
>
>Which is something that's necessarily language-specific. You can't even
>say what calling a C++ function means without reference to conscepts
>specific to the language it's called from. That's not quite true: you
>could achieve language independence, at the cost of losing platform
>independence, by specifying the function call interface.
Even though the implementation of "extern "<name>"..." for each language
<name> will be specific to that language, it does not means that every
feature of the language interface needs to be language specific. In fact
we encountered two such examples earlier in this thread:
One was the suggestion that C++ global data should be initialized before
being used. This was in fact the main hurdle when interfacing C++ with
other languages. It is fairly easy to find at least one such
implementation, namely each piece of global data having a bit telling if
it is initialized or not, and when it is being called, checking this bit
of to see if it must be initialized before use. (And if C++ global data is
to be loaded dynamically, one must implement such a feature anyway, if
calling is "lazy".)
The other example was given from Ada, which had such formulations which
did not specifically name any other language.
Another problem with C++ is the exceptions, so something must be said is
what is expected there, but this need not be said in words relating to
every other specific language: One needs to know what is required in terms
of behavior if C++ exceptions should be able to pass through object code
produced by another language.
Clearly, there will be a lot of implicit assumptions on any of that other
language, such as that it calls functions and put the local variables on a
stack and such. But this needs not really be a concern of a C++ standard,
it needs to merely list expected behavior in the case one succeeds to
implement an "extern "<name>" ... " construct.
It is also possible to put more extensive details of C++ interfacing with
specific language into another standard specifically dedicated to that
issue. The C++ standard can then refer to it instead, only otherwise
mentioning a few more general facts.
Hans Aberg * Anti-spam: remove "remove." from email address.
* Email: Hans Aberg <remove.haberg@member.ams.org>
* Home Page: <http://www.matematik.su.se/~haberg/>
* AMS member listing: <http://www.ams.org/cml/>
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: jthill@telus.net (Jim Hill)
Date: Tue, 31 Oct 2000 22:00:32 GMT Raw View
Hans Aberg <remove.haberg@matematik.su.se> wrote:
> I have [as a] given:
> pascal short main(CWPluginContext context);
What should the C++ standard say about this? It doesn't even pretend to
be standard C++.
If the declaration were `extern "Pascal" short plugin` one could argue
that the implementation permits `plugin` to be written in standard C++,
and so must meet the standard's requirements.
Jim
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: James Kuyper <kuyper@wizard.net>
Date: Tue, 31 Oct 2000 16:45:54 GMT Raw View
Hans Aberg wrote:
> In article <39EE2BA4.2BC7C877@sun.com>, Steve Clamage
> <stephen.clamage@sun.com> wrote:
-...
> >To specify details of support for languages other than C would
> >require the C++ standard to track other language standards.
> No, this is not really needed: All that is needed is describing how C++
> should behave when called from another language. In addition one could add
Which is something that's necessarily language-specific. You can't even
say what calling a C++ function means without reference to conscepts
specific to the language it's called from. That's not quite true: you
could achieve language independence, at the cost of losing platform
independence, by specifying the function call interface.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: Mon, 30 Oct 2000 18:25:37 GMT Raw View
In article <39EE2BA4.2BC7C877@sun.com>, Steve Clamage
<stephen.clamage@sun.com> wrote:
>> So this yet another weakness of the C++ standard: It should not only tell
>> that it is legal to have main in C, but also when the C++ data should be
>> initialized.
>
>But you never need to write main in C. If you have an existing main
>in C that can't be compiled as C++, you can change its name to,
>for example, C_main, and write a C++ main:
>
>extern "C" int C_main(int, char**);
>int main(int argc, char** argv) { return C_main(argc, argv); }
This is an interesting idea, but it does not work in general: The problem
is that one already has a program that has exported the name _and_ the
language, and you want to write a DLL. Then the situation you are facing
that you have two languages that should work together.
So, in a situation I am facing now, writing a compiler plugin to an
already existing IDE (integrated development envrionment), I have given:
pascal short main(CWPluginContext context);
I have to write this function. Now the (not-so) funny thing happens is
that even though initialialization with C functions is OK in the sense
that then C++ is also initialized, I have now verified that in this case
the C++ functions are not initialized. Even further, C++ exceptions are
not caught properly, even if the throw/catch is entirely within C++ code.
>To specify details of support for languages other than C would
>require the C++ standard to track other language standards.
No, this is not really needed: All that is needed is describing how C++
should behave when called from another language. In addition one could add
suggeestion for the names to use when extending the "extern "<name>"
directive.
If somebody writes a C++ compiler and extends it with another language,
then that person will know what will be required.
>For example,
>consider Fortran: should compatibility with all 4 current standards
>be required, or some subset of them?
So one who writes a C++ compiler could choose exactly which versions to
choose: That will not be a part of the C++ standard.
>Instead of trying to slay that dragon, I think it is better to leave
>it as a market-driven issue.
Well, I don't think there will be needed dragon-slaying in order to fix
this issue.
Hans Aberg * Anti-spam: remove "remove." from email address.
* Email: Hans Aberg <remove.haberg@member.ams.org>
* Home Page: <http://www.matematik.su.se/~haberg/>
* AMS member listing: <http://www.ams.org/cml/>
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: kanze@gabi-soft.de
Date: Sun, 15 Oct 2000 03:36:59 GMT Raw View
Jim Hyslop <jim.hyslop@leitch.com> writes:
|> > Or the C++ standard should be augmented to have a statement
|> > export "C" { ... };
|> > where one can export some hooks for use with C.
|> extern "C" works just fine for this.
|> // file: tcpp.cpp
|> #include <iostream>
|> extern "C"
|> {
|> void helloCPlusPlus()
|> { std::cout << "Hello, C++ world!" << std::endl; }
|> }
|> // end file tcpp.cpp
|> // file: test.c
|> #include <stdio.h>
|> extern void helloCPlusPlus();
|> int main()
|> {
|> printf("Hello, C World!\n");
|> fflush(stdout);
|> helloCPlusPlus();
|> }
|> // end file test.c
|> The two files compile and link cleanly, and give the expected output:
|> Hello, C World!
|> Hello, C++ World!
You were lucky. In general, you cannot expect for C++ classes to work
correctly unless main is written in C++. (I'm actually rather surprised
that cout worked. I suppose that this is a side effect of what makes it
work in static initializers, which may also be called before main.)
--=20
James Kanze mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: 2000/10/15 Raw View
In article <remove.haberg-1310002038450001@du138-226.ppp.su-
anst.tninet.se>, Hans Aberg <remove.haberg@matematik.su.se> writes
>Or the C++ standard should be augmented to have a statement
> export "C" { ... };
>where one can export some hooks for use with C.
apart from the fact that that is exactly what extern"C" does, there is
the point that there is no such thing as a single kind of C 'linkage'
because C does not define what that might mean. Indeed it is not unusual
to find that the object code of one C library is incompatible with that
of another or with your object code. So how exactly do you propose that
such compatibility should exist? We may be pretty good at writing rules
but we are not magicians nor should we require implementors to be.
Francis Glassborow Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: 2000/10/15 Raw View
In article <7yJF5.78$OD4.754@burlma1-snr2>, Barry Margolin
<barmar@genuity.net> wrote:
>>May I point out that not being able to call C++ from C hurts the use of
>>C++
...
>This could be difficult to make work. C++ allows arbitrary code to be run
>to initialize static variables, whereas C requires static initializers to
>be constants, and there may be some additional bookkeeping that has to be
>done at startup time (perhaps constructing virtual tables). Typically,
>this is implemented in C++ by automatically creating an initialization
>function that runs before main(), but this requires that a C++ compiler is
>processing the source module containing main(). If main() is compiled by a
>C compiler, it will set up the normal startup linkage, and when C++
>functions get called none of the setup will have been done.
The problem seems to not have anything to do with what the C compiler does
at all: It is rather up to the linker to discover that C++ code is called,
and make sure that the right initializations take place.
The same problem happens when C++ code calls a DLL (dynamically linked
library) written in C++: Then the global variables of that C++ library
must be initialized before it is used.
So in fact every dynamically loaded C++ entity must have such an
initialization function that is called first. If a C++ entity is called
statically, there must be a initialization function that the linker can
put in statically.
In article <86y9zrpcgf.fsf@gabi-soft.de>, kanze@gabi-soft.de wrote:
>|> int main()
>|> {
>|> printf("Hello, C World!\n");
>|> fflush(stdout);
>|> helloCPlusPlus();
>|> }
>|> // end file test.c
...
>You were lucky. In general, you cannot expect for C++ classes to work
>correctly unless main is written in C++. (I'm actually rather surprised
>that cout worked. I suppose that this is a side effect of what makes it
>work in static initializers, which may also be called before main.)
So it seems to be rather be a problem that a system
(compiler-linker-runtime system) makes sure that C++ initializations
always takes place correctly, otherwise it does not comply with the C++
standard.
I have otherwise used such combinations with a C compiler creating
functions with extern Pascal linkage which then are used by Pascal
functions, under MacOS, as MacOS originally was written in Pascal. C and
Pascal does not have the same dynamic type of initializations as C++ which
in effect requires functions to be called. But otherwise the situation is
the same.
For example, under MacOS, if one writes a program that can handle
AppleEvents (binary data that programs send to each other), the MacOS
routines handling AppleEvents need a Pascal procedure that the programmer
writes. Then one can write that in C, but giving it external Pascal
linkage.
C version:
pascal handleThisOrThatEvent() { /* C code */ }
C++ version:
extern "Pascal" handleThisOrThatEvent() { /* C++ code */ }
Then this handleThisOrThatEvent() will be exported and used by a MacOS
routine that originally had its top-node main written in Pascal.
So if the handshake does not work, it seems that it is something wrong on
the whole system that implements C/C++.
But the C++ should explain this clearly, so that both user of C++ and
those that implement get to know it.
Hans Aberg * Anti-spam: remove "remove." from email address.
* Email: Hans Aberg <remove.haberg@member.ams.org>
* Home Page: <http://www.matematik.su.se/~haberg/>
* AMS member listing: <http://www.ams.org/cml/>
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: 2000/10/15 Raw View
In article <kPns$SBzpM65Ewpy@ntlworld.com>, Francis Glassborow
<francisG@robinton.demon.co.uk> wrote:
>apart from the fact that that is exactly what extern"C" does, there is
>the point that there is no such thing as a single kind of C 'linkage'
>because C does not define what that might mean. Indeed it is not unusual
>to find that the object code of one C library is incompatible with that
>of another or with your object code. So how exactly do you propose that
>such compatibility should exist?
As everybody knows, the set of compilers used for the different languages
must be attuned together for this to work.
This is not only a problem when using compilers for different languages,
but a problem when using the same compiler together with libraries
compiled with various options. One can only hope that the linker discovers
the mistake.
For example, a few days ago I used a very complyant C++ compiler and got
the following link error:
undefined 'std::ctype<char>::ctype(const std::ctype_base::mask*, char,
unsigned long)' (code)
Referenced from 'std::ctype<char>::ctype()' in lex.Calculator.cc
After several hours work, I realized that I inadvertently had turned an
option "enable bool support" off. It caused std::istream.get() to fail.
>We may be pretty good at writing rules
>but we are not magicians nor should we require implementors to be.
So the standard contains the language hooks so that different languages
can work together, but it is up to the implementer of the set of compilers
for the different languages to tune them together.
Hans Aberg * Anti-spam: remove "remove." from email address.
* Email: Hans Aberg <remove.haberg@member.ams.org>
* Home Page: <http://www.matematik.su.se/~haberg/>
* AMS member listing: <http://www.ams.org/cml/>
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: Andrew J Robb <ajrobb@pavilion.co.uk>
Date: 2000/10/15 Raw View
Hans Aberg wrote:
> May I point out that not being able to call C++ from C hurts the use of
> C++, because one cannot switch from C to C++ and expect that program to be
> used as a library by a program written in C.
>
> So therefore I think that either the C standard should be augmented to to
> have a C++ style statement
> extern "C" { ... };
> where ... should be able to contain at least simple function calls.
>
> Or the C++ standard should be augmented to have a statement
> export "C" { ... };
> where one can export some hooks for use with C.
>
> Hans Aberg * Anti-spam: remove "remove." from email address.
> * Email: Hans Aberg <remove.haberg@member.ams.org>
> * Home Page: <http://www.matematik.su.se/~haberg/>
> * AMS member listing: <http://www.ams.org/cml/>
>
> ---
> [ comp.std.c++ is moderated. To submit articles, try just posting with ]
> [ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
> [ --- Please see the FAQ before posting. --- ]
> [ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
> [ Note that the FAQ URL has changed! Please update your bookmarks. ]
pardon me if I am missing the point, but why don't you use something like:
extern "C" void cplusplusFunction()
{
class Fred fred; // use C++
...
}
I have never had a problem getting this to work. This allows me to mix C and
C++ calling both ways.
I think the only C++ functionality that is lost is that the C-callable
functions cannot be overloaded (because their names aren't mangled).
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: 2000/10/16 Raw View
In article <39E8ADF6.82CBE45E@pavilion.co.uk>, Andrew J Robb
<AJRobb@bigfoot.com> wrote:
>pardon me if I am missing the point, but why don't you use something like:
>
>extern "C" void cplusplusFunction()
>{
> class Fred fred; // use C++
> ...
>}
Right, this is the same as
extern "C" { void cplusplusFunction() { /* C++ code */ } }
-- It is in fact easy to check if the C++ is initialized, even if main()
is in C; simply add some C++ global data:
// In C++ file:
class A {
public:
A() { std::cout << "Initializing A data." << std::endl; }
};
const A a; // Some global data.
// In C file:
int main() { ... }
If the compiler/linker and stuff correctly keeps track of the C++ data,
then one will at startup get a printout
Initializing A data.
even if the C-code is not somehow linked up with the use of the A. -- If
C++ global data has such constructors with global effects, it will be
impossible for a smart linker to exclude that data, even if the program
itself is written just in C.
-- But I am not sure what the C++ standard says about _when_ the global
data should be initialized. Perhaps only before the first use. In such a
case, it would be legal to optimize away the "const A a" above. Then one
would have to add say
// In C++ file:
extern "C" void f() { /* C++ code using "a". */ }
// In C file:
void main() { /* C code */ f(); ... }
But my compiler does not do that.
Global C++ data can of course be initialized at any time, as a matter of
practical implementation: One just keeps track of the initialization with
a variable, say a bit. If some C++ data is accessed one checks that bit
and initializes the data, if it has not already been initialized;
otherwise do nothing.
Hans Aberg * Anti-spam: remove "remove." from email address.
* Email: Hans Aberg <remove.haberg@member.ams.org>
* Home Page: <http://www.matematik.su.se/~haberg/>
* AMS member listing: <http://www.ams.org/cml/>
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: comeau@panix.com (Greg Comeau)
Date: 2000/10/16 Raw View
In article <remove.haberg-1610001627020001@du134-226.ppp.su-anst.tninet.se>,
Hans Aberg <remove.haberg@matematik.su.se> wrote:
>-- It is in fact easy to check if the C++ is initialized, even if main()
>is in C; simply add some C++ global data:
> // In C++ file:
> class A {
> public:
> A() { std::cout << "Initializing A data." << std::endl; }
> };
>
> const A a; // Some global data.
>
> // In C file:
> int main() { ... }
>
>If the compiler/linker and stuff correctly keeps track of the C++ data,
>then one will at startup get a printout
> Initializing A data.
>even if the C-code is not somehow linked up with the use of the A.
Many implementations will exhibit behavior just as you say,
but just a comment that what you've offered is beyond the scope
of the Standard (C's or C++'s), so there is not such guarantee that
it will.
>-- If
>C++ global data has such constructors with global effects, it will be
>impossible for a smart linker to exclude that data, even if the program
>itself is written just in C.
Impossible? It's up to whatever the vendor defines the "linker"
as doing, or not doing.
>-- But I am not sure what the C++ standard says about _when_ the global
>data should be initialized. Perhaps only before the first use.
If main() is in C, it says nothing, it's beyond the scope of the standard.
> In such a
>case, it would be legal to optimize away the "const A a" above.
Perhaps, but if nothing else, the effect of your I/O can't be
optimized away.
>Then one
>would have to add say
> // In C++ file:
> extern "C" void f() { /* C++ code using "a". */ }
> // In C file:
> void main() { /* C code */ f(); ... }
>But my compiler does not do that.
>
>Global C++ data can of course be initialized at any time, as a matter of
>practical implementation: One just keeps track of the initialization with
>a variable, say a bit. If some C++ data is accessed one checks that bit
>and initializes the data, if it has not already been initialized;
>otherwise do nothing.
If you mean doing it all yourself, sure, that's always possible,
and some would say the preferred route.
- Greg
--
Comeau Computing / Comeau C/C++ "so close" 4.2.44 betas NOW AVAILABLE
TRY Comeau C++ ONLINE at http://www.comeaucomputing.com/tryitout
Email: comeau@comeaucomputing.com / WEB: http://www.comeaucomputing.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: David R Tribble <david@tribble.com>
Date: 2000/10/16 Raw View
Hans Aberg wrote:
>> Or the C++ standard should be augmented to have a statement
>> export "C" { ... };
>> where one can export some hooks for use with C.
prj@po.cwru.edu (Paul Jarc) wrote:
>> This is already the case, with extern "C", AIUI. extern "C" means
>> that the entity being declared, regardless of what language it's
>> implemented in, has C-style linkage, so it's accessible from C.
Hans Aberg wrote:
> Right, I was blinded to the fact that the extern "C" clause only
> applies to the linkage of the function declared and not in it.
C++ specifically allows two linkages for (non-member) functions:
extern "C" { ... }
extern "C++" { ... } // default linkage
Other linkages (e.g., extern "pascal") can be supported, but are not
mandated.
You must realize also that calling C++ from C (or C from C++)
requires a C++ program execution environment, i.e., the program
containing the C and C++ functions must be a C++ program (having
a main() compiled as C++). This is necessary because of runtime
startup and initializations needed by C++ that generally are not
needed for C. The same is usually true of dynamic shared libraries,
too, i.e., they must be C++ libraries (created by a C++ linker).
Calling C++ member functions from C is possible, but highly
unportable, because of the implicit 'this' pointer that needs to
be supplied. The general approach is to invoke the mangled C++
function name directly as a C function from C code, passing it a
void* pointer as the 'this' pointer. Even so, there's no guarantee
that it will work, and if it works on one system it certainly won't
work as is on any other system. I've had to do such horrible things
in the past, but I recommend avoiding such horrors. It's better to
use a C++ non-member function with extern C linkage as a helper
function to invoke the C++ member function.
--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 2000/10/17 Raw View
David R Tribble <david@tribble.com> writes:
>You must realize also that calling C++ from C (or C from C++)
>requires a C++ program execution environment, i.e., the program
>containing the C and C++ functions must be a C++ program (having
>a main() compiled as C++).
This is implementation-dependent. For example, it is NOT true for GNU
C / GNU C++ (on all platforms). I think it is also not true for most
implementations that use the ELF object file format, which includes
most modern UNIX implementations.
Unfortunately, despite the increasing importance of multi-language
programming, the C and C++ standards do not address this issue.
So it's just a quality of implementation issue.
Note that the Ada 95 standard does address this issue. The section in
question is only "Implementation advice", not a requirement for conformance,
but each Ada 95 implementation is required to document whether or not
it follows that advice.
| B.1 Interfacing Pragmas
|
| Implementation Advice
|
| (39)
| If an implementation supports pragma Export to a given
| language, then it should also allow the main subprogram to be
| written in that language. It should support some mechanism for
| invoking the elaboration of the Ada library units included in
| the system, and for invoking the finalization of the
| environment task. On typical systems, the recommended
| mechanism is to provide two subprograms whose link names are
| "adainit" and "adafinal". Adainit should contain the
| elaboration code for library units. Adafinal should contain
| the finalization code. These subprograms should have no effect
| the second and subsequent time they are called.
I think it would be a good idea for the next C++ standard to include
a similar requirement.
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: prj@po.cwru.edu (Paul Jarc)
Date: 2000/10/17 Raw View
remove.haberg@matematik.su.se (Hans Aberg) writes:
> The C extern Pascal construct on my compiler looks like
> pascal aPascalFunction(...) { /* C Code */ }
> If the C++ compiler does not have a Pascal extension, one must write
> extern "C" { pascal aPascalFunction(...) { /* C++ Code */ } }
That won't work. The 'pascal' above still occurs in C++ code, so if
the C++ compiler doesn't support that, wrapping it in extern "C" won't
help. This also wouldn't work:
extern "C" func(); // declaration in C++
pascal func() { ... } /* definition in C */
because you'd be lying to the C++ compiler about func's linkage.
You'd need a C++-callable C-linkage C function that calls the
C-callable Pascal-linkage Pascal function, or in the other direction,
a Pascal-callable Pascal-linkage C function that calls the C-callable
C-linkage C++ function.
> -- The problem with the C programming, apart from that it is slow, is that
> one tends to get lots of statically allocated arrays with the potential of
> breaking if say a string becomes too long or something.
That's a problem with some C programmers, not with C programming.
paul
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: comeau@panix.com (Greg Comeau)
Date: 2000/10/17 Raw View
In article <8sh07l$3l0$1@mulga.cs.mu.OZ.AU>,
Fergus Henderson <fjh@cs.mu.OZ.AU> wrote:
>David R Tribble <david@tribble.com> writes:
>>You must realize also that calling C++ from C (or C from C++)
>>requires a C++ program execution environment, i.e., the program
>>containing the C and C++ functions must be a C++ program (having
>>a main() compiled as C++).
>
>This is implementation-dependent. For example, it is NOT true for GNU
>C / GNU C++ (on all platforms). I think it is also not true for most
>implementations that use the ELF object file format, which includes
>most modern UNIX implementations.
>
>Unfortunately, despite the increasing importance of multi-language
>programming, the C and C++ standards do not address this issue.
>So it's just a quality of implementation issue.
I'm having a problem following how the conclusion in your
last line is supported by those above it. That is, doesn't
the C++ Standard describe C++ programs at some level?
If so, then main is required (at least in hosted environments),
and since it is a function that will be written in C++,
then it follows that the C++ Standard describes it too.
So how can it be implementation-defined that main can be in some
other language? Apologizies in advance if I've misinterpreted
your statements. I realize the practicalities that it actually
might be in some other language (at least C code that looks like
C++) so long as it also adheres to what C++ requires, but
I find that kinda accidental if you will.
- Greg
--
Comeau Computing / Comeau C/C++ "so close" 4.2.44 betas NOW AVAILABLE
TRY Comeau C++ ONLINE at http://www.comeaucomputing.com/tryitout
Email: comeau@comeaucomputing.com / WEB: http://www.comeaucomputing.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: kuehl@ramsen.informatik.uni-konstanz.de (Dietmar Kuehl)
Date: 2000/10/17 Raw View
Hi,
Greg Comeau (comeau@panix.com) wrote:
: So how can it be implementation-defined that main can be in some
: other language?
I can imagine executation environments where multiple languages can be
mixed. However, like the C++ runtime requires some initialization, the
C runtime (which just happens to be basically a subset of the C++
runtime), and probably any other language runtime at least has to be
initialized. Since mixing multiple languages in just one program
(somewhat brought forward eg. be Microsoft's .Net architecture) can be
benefitial (eg. a computation core in Fortran, a GUI in Java, database
access in C++, custom I/O in C, interprocess communication in another
language, etc.) it makes very well sense to somehow open the
executation environment to kind of "register" multiple languages. The
basic reason why gcc is "C++ independent" is that the startup code even
for C programs is aware of C++, ie. there is already a hook eg. for
the constructors and destructors even in C programs linked with gcc.
Practically, I think that it is possible to have some startup code
which is language independent and finally calls some "user level
main()" once initialization of the runtime and eg. user objects with
static linkage are constructed. It does not really matter what language
this "user level main()" is implemented in. What is important is that
language specific initialization is run before it is called for all
used languages, including C++. However, thist stuff is not really to be
addressed by the language standard. It may be part of a platform ABI,
however.
I'm not 100% sure but I think that the gcc approach does just this, at
least on ELF platforms (I haven't looked into other platform's startup
code): Basically there are a startup and finalize section which is
accumulated over the object files. These sections will contain code
calling into initialization and finalization routine, eg. to
construct/destruct objects with static linkage. Any language dependent
initialization can be put there. The initialization code is called
prior to some 'main()' function and the finalization code afterwards.
Unfortunately, gcc does not use this approach to initialize C stuff:
Eg. the I/O stuff is always initialized, whether it is used or not...
--
<mailto:dietmar_kuehl@yahoo.de>
<http://www.fmi.uni-konstanz.de/~kuehl/>
I am a realistic optimist - that's why I appear to be slightly pessimistic
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: Pete Becker <petebecker@acm.org>
Date: Wed, 18 Oct 2000 01:08:21 GMT Raw View
Greg Comeau wrote:
>
> So how can it be implementation-defined that main can be in some
> other language? Apologizies in advance if I've misinterpreted
> your statements. I realize the practicalities that it actually
> might be in some other language (at least C code that looks like
> C++) so long as it also adheres to what C++ requires, but
> I find that kinda accidental if you will.
>
I think Fergus' message muddled the issue a little. The C++ standard
says that main must be written in C++. It also talks about the effect of
'extern "C"'. with the result being that there's a chance that you can
intermix C++ code (which includes main) with functions labeled 'extern
"C"' and written in C. Fergus made the complementary point that with
many C and C++ implementations, it doesn't matter whether main is
compiled as C code or C++ code. Static initializers work right, etc. So
as long as you get the names and the calling convention right you can
intermix C and C++. That's much more implementation-dependent than
merely using 'extern "C"' and a suitable C compiler, but it often works.
--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Contributing Editor, C/C++ Users Journal (http://www.cuj.com)
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: 2000/10/18 Raw View
In article <8sh07l$3l0$1@mulga.cs.mu.OZ.AU>, fjh@cs.mu.OZ.AU (Fergus
Henderson) wrote:
>>You must realize also that calling C++ from C (or C from C++)
>>requires a C++ program execution environment, i.e., the program
>>containing the C and C++ functions must be a C++ program (having
>>a main() compiled as C++).
>
>This is implementation-dependent. For example, it is NOT true for GNU
>C / GNU C++ (on all platforms). I think it is also not true for most
>implementations that use the ELF object file format, which includes
>most modern UNIX implementations.
I use the Metrowerks CW (CodeWarrior), and on that it was OK to have a C
main() calling a C++ function.
-- In fact, I suspect that on older systems one could not have it that
way, but newer systems have fixed it.
Anyway, it is important to be able to have C functions, including main()
calling C++, as one might write a library in C++, which should be called
by a program written in C.
>Unfortunately, despite the increasing importance of multi-language
>programming, the C and C++ standards do not address this issue.
>So it's just a quality of implementation issue.
I think this is a weakness of the C++ standard. It should clearly state
that such a mixture is allowed, to ensure that implementations can handle
it.
>Note that the Ada 95 standard does address this issue. The section in
>question is only "Implementation advice", not a requirement for conformance,
>but each Ada 95 implementation is required to document whether or not
>it follows that advice.
...
> | If an implementation supports pragma Export to a given
> | language, then it should also allow the main subprogram to be
> | written in that language.
...
> | On typical systems, the recommended
> | mechanism is to provide two subprograms whose link names are
> | "adainit" and "adafinal".
...
>I think it would be a good idea for the next C++ standard to include
>a similar requirement.
I fully agree. Also, the C++ seems to lack such recommendations:
In article <39EB2DE9.BAB44CC@tribble.com>, David R Tribble
<david@tribble.com> wrote:
>Other linkages (e.g., extern "pascal") can be supported, but are not
>mandated.
One type of recommendation could what names to use for some other
languages. (And perhaps what file name extension to use -- perhaps a topic
for another thread...)
In article <8sfg0s$avn$1@panix3.panix.com>, comeau@comeaucomputing.com wrote:
>>-- But I am not sure what the C++ standard says about _when_ the global
>>data should be initialized. Perhaps only before the first use.
>
>If main() is in C, it says nothing, it's beyond the scope of the standard.
So this yet another weakness of the C++ standard: It should not only tell
that it is legal to have main in C, but also when the C++ data should be
initialized.
>> In such a
>>case, it would be legal to optimize away the "const A a" above.
>
>Perhaps, but if nothing else, the effect of your I/O can't be
>optimized away.
If a future C++ standard says that global data only need be initialized
before the main() program references it, it is possible to optimize away
such global data, even if it contains side effects such as IO: If the data
is never referenced, it needs not be initialized, and the IO will not
happen.
In fact, I think this would be the preferred statement, because one could
make sure a compilation behaves the same, even if some extra C++ libraries
are added: If global data in the C++ libraries never is referenced, it can
be optimized away. If it is in a DLL, it needs only be initialized when
referenced the first time.
>>Global C++ data can of course be initialized at any time, as a matter of
>>practical implementation: One just keeps track of the initialization with
>>a variable, say a bit. If some C++ data is accessed one checks that bit
>>and initializes the data, if it has not already been initialized;
>>otherwise do nothing.
>
>If you mean doing it all yourself, sure, that's always possible,
>and some would say the preferred route.
Then one will pretty much land on a compiler implementation like the one I
described above. -- So one would not need to do it by hand oneself. :-)
Hans Aberg * Anti-spam: remove "remove." from email address.
* Email: Hans Aberg <remove.haberg@member.ams.org>
* Home Page: <http://www.matematik.su.se/~haberg/>
* AMS member listing: <http://www.ams.org/cml/>
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: Andrew J Robb <andrew@localhost.localdomain.screaming.net>
Date: 2000/10/18 Raw View
Hans Aberg wrote:
[snip]
> -- It is in fact easy to check if the C++ is initialized, even if main()
> is in C; simply add some C++ global data:
[snip]
I would not propose that calling C++ from a C program should be supported by
the standard.
Instead, I do have use for embedding C routines in C++ programs, where the C
routines can
call C++ funtions with extern "C" linkage.
Where I want to invoke methods on a class from within C (e.g. from Oracle
Pro*C),
I sidestep the issue by using function pointers to static methods.
Example:
header file, Cstruct.h
#ifndef CSTRUCT_INCLUDED
#define CSTRUCT_INCLUDED
/* declaration of a struct and a function type, shared by C and C++ */
struct Cstruct;
typedef void (*Method)(Cstruct *);
#ifdef __cplusplus
// C++ definition of Cstruct
// for brevity I shall defy convention and declare a static method within a
struct
struct Cstruct
{
....
// static method that matches the function pointer, Method
static void someMethod(Cstruct *);
};
extern "C" { // C++ declaration of C linkage
#endif /*__cplusplus*/
/* shared declaration of C function */
void Cfunction(struct Cstruct *, Method);
#ifdef __cplusplus
} // extern "C"
#endif
#endif /*CSTRUCT_INCLUDED*/
I can then pass a pointer to Cstruct, ptr, and a function pointer to
Cstruct::someMethod to a C function,
which then uses method(ptr):
/* embedded C routine that calls C++ */
#include "Cstruct.h"
void Cfunction(struct Cstruct * ptr, Method method)
{
....
method(ptr);
....
}
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: James Kuyper <kuyper@wizard.net>
Date: 2000/10/18 Raw View
Pete Becker wrote:
...
> I think Fergus' message muddled the issue a little. The C++ standard
> says that main must be written in C++. ...
That's true of a pure C++ program, but the C++ standard does not and
cannot constrain the behavior of a program that includes components
written in other languages.
The C++ standard says that "Linkage from C++ to objects defined in other
languages and to objects define in C++ from other languages is
implementation defined and language-dependent.". I couldn't find any
other part of the standard that defines anything more specific about how
mixed language programming works.
It doesn't even guarantee that there exists any C compiler capable of
compiling C code in a way that's compatible with C++. The only thing
that the C++ standard guarantees about the behavior of an extern "C"
function is what happens if both the definition of the function and the
call to the function occur in C++ code.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 2000/10/18 Raw View
comeau@panix.com (Greg Comeau) writes:
>Fergus Henderson <fjh@cs.mu.OZ.AU> wrote:
>>David R Tribble <david@tribble.com> writes:
>>>You must realize also that calling C++ from C (or C from C++)
>>>requires a C++ program execution environment, i.e., the program
>>>containing the C and C++ functions must be a C++ program (having
>>>a main() compiled as C++).
>>
>>This is implementation-dependent. [...]
>>Unfortunately, despite the increasing importance of multi-language
>>programming, the C and C++ standards do not address this issue.
>>So it's just a quality of implementation issue.
>
>I'm having a problem following how the conclusion in your
>last line is supported by those above it. That is, doesn't
>the C++ Standard describe C++ programs at some level?
Yes. But here we are talking about combined C/C++ programs.
The C++ standard really doesn't say much about those.
>If so, then main is required (at least in hosted environments),
>and since it is a function that will be written in C++,
>then it follows that the C++ Standard describes it too.
>So how can it be implementation-defined that main can be in some
>other language?
In complete C++ programs, a main function (presumably C++) is required,
according to the ISO C++ standard 3.6.1 paragraph 1. If not, program
is ill-formed, and the implementation must issue a diagnostic.
In complete C programs, a main function is required, otherwise the
behaviour is undefined. (This is one of those cases where the behaviour
is implicitly undefined due to lack of any explicit definition in
normative text, but for clarity it is explicitly mentioned as being
undefined in non-normative text in the fourth point of ISO C Appendix
J.2 paragraph 1.) No diagnostic is required if main() is not defined.
Although they are worded differently, the result is basically the same
in each language: apart from the difference about whether a diagnostic
is required, these requirements are symmetric.
Neither standard explicitly states that what language main() must be
in, so one reasonable interpretation is that for combined C/C++
programs, main can be defined in either language.
I'll call this interpretation "interpretation A".
Another reasonable interpretation, which I'll call "interpretation B",
is that each standard means that main() must be defined in its own
language. This seems to be how you (Greg Comeau) have interpreted the
C++ standard. If we take that interpretation of the C and C++
standards, and then furthermore ("interpretation B++" ;-) try to apply
it to combined C/C++ programs, we end up with the requirement that
main() must be defined in *both* C and C++! This conflicts with the
ODR, so this interpretation is clearly contradictory.
But in fact interpretation B++ (applying interpretation B to combined
C/C++ programs) may not be reasonable, even apart from the
contradiction that results. Even if we assume that the requirement in
3.6.1 that C++ programs have a main() means that they must have a C++
main(), this requirement is clearly a requirement on C++ PROGRAMS, and
ISO C++ 7.5 [decl.link] paragraph 2, which describes the `extern "C"'
feature, says "Linkage between C++ and non-C++ CODE FRAGMENTS can be
achieved using a linkage-specification". Although C++ programs must
define main(), it is clearly not a requirement for C++ code fragments
to define main().
Unfortunately that sentence in 7.5p2 is ambiguous; it's not clear
whether it means (1) "Linkage between {C++} and {non-C++ code fragments}"
or (2) "Linkage between {C++ and non-C++} code fragments". If we take the
latter interpretation, then it means that we can link C++ code
fragments with non-C++ code fragments, and so I'd argue main()
need not be defined in C++. If we take the former interpretation,
this might just be saying that we can link C++ programs with
non-C++ code fragments, in which case the requirements on C++
programs might still apply.
On the other hand, 7.5p2 just says "linkage ... CAN be achieved".
This is just a statement of fact; since it does not use the words
"shall" or "may", it is not a requirement or a permission.
The only requirement is in 7.5p3:
| 7.5 - Linkage specifications [dcl.link]
|
| -2- Linkage (basic.link) between C++ and non-C++ code fragments can be achieved using a
| linkage-specification:
[...]
| -3- Every implementation shall provide for linkage to functions written in the C
| programming language, "C", and linkage to C++ functions, "C++".
But here the meaning of "provide for linkage" is unclear.
7.5p3 could be interpreted as (i) a requirement that C++ implementations
shall provide some means for C++ programs to be linked with C
functions (and thus that every conforming C++ implementation must be
compatible with at least one C implementation),
or as (ii) just saying that C++ implementations must allow
the use of "C" as a linkage-specification, but don't
have to provide any way to actually link with C functions.
If we take interpretation (ii), then neither the C standard
nor the C++ standard gives any guarantees about combined
C/C++ programs, and so basically all bets are off.
If we take interpretation (i), then
So, in summary, we have numerous alternative interpretations:
- interpretation (i): C++ implementations must support
combined C/C++ programs, and
- interpretation A: main must be defined, but the definition
can be in either (or indeed any?) language
- interpretation B++: main must be defined in both C and C++
and must only be defined once (contradictory)
- interpretation B (1): you may link C++ programs with
C code fragments, but main must be defined in C++
- interpretation B (2): the C++ part may be just a
code fragment, and so it need not define main
- interpretation (ii): the C and C++ standards don't require
implementations to support combined C/C++ programs, so if
you write a combined C/C++ program all bets are off.
Consult your implementation's documentation.
Some implementations require main() to be in C++.
Apart from interpretation B++, which is contradictory, I don't see any
way to rule any of these interpretations out using the normative text
in the two standards.
Interpretation (ii) "all bets are off" is clearly undesirable, but
requiring each C++ implementation to support linking with C also has
its drawbacks. Perhaps the best thing would be to define a separate
standard for combined C/C++ implementations, which would incorporate
by reference the relevant provisions of the C and C++ standards.
Such a standard could take the opportunity to clarify the issues
that I've mentioned above for which the current standards do not give
clear guidance.
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: 2000/10/18 Raw View
In article <m31yxf4g7o.fsf@multivac.student.cwru.edu>, prj@po.cwru.edu
(Paul Jarc) wrote:
>> The C extern Pascal construct on my compiler looks like
>> pascal aPascalFunction(...) { /* C Code */ }
>> If the C++ compiler does not have a Pascal extension, one must write
>> extern "C" { pascal aPascalFunction(...) { /* C++ Code */ } }
>
>That won't work. The 'pascal' above still occurs in C++ code, so if
>the C++ compiler doesn't support that, wrapping it in extern "C" won't
>help.
When you mentioned it, I have never used it that way: I have so far always
put the stuff in a C file, with the construct I know that the compiler can
handle, which for the compiler in question is
pascal myPascalFunctionWrittenInC(...) { /* C code */ }
The other variation is putting it in a C++ file with the construct
extern "Pascal" myPascalFunctionWrittenInCplusPlus(...) { /* C++ code */ }
which I know the compiler accepts.
The acceptance of Pascal is a special thing, because it is under MacOS
which was originally written in that language. So therfore the compiler
might be able to cope with other variations, as well, but I have no idea.
Hans Aberg * Anti-spam: remove "remove." from email address.
* Email: Hans Aberg <remove.haberg@member.ams.org>
* Home Page: <http://www.matematik.su.se/~haberg/>
* AMS member listing: <http://www.ams.org/cml/>
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 2000/10/18 Raw View
Pete Becker <petebecker@acm.org> writes:
>Greg Comeau wrote:
>>
>> So how can it be implementation-defined that main can be in some
>> other language?
[...]
>
>I think Fergus' message muddled the issue a little. The C++ standard
>says that main must be written in C++. It also talks about the effect of
>'extern "C"'. with the result being that there's a chance that you can
>intermix C++ code (which includes main) with functions labeled 'extern
>"C"' and written in C.
That's one reasonable interpretation. But as I have just explained
in detail in another message, I think there are quite a few other
reasonable interpretations.
Note that your interpretation gives no guarantees.
It only offers "a chance" that things might work.
It would be equally valid to say that there's also
"a chance" that you can intermix C++ code which does
NOT include main() with functions labeled `extern "C"'
and written in C.
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: 2000/10/18 Raw View
In article <8sig85$2jc$1@panix3.panix.com>, comeau@comeaucomputing.com wrote:
>In article <8sh07l$3l0$1@mulga.cs.mu.OZ.AU>,
>Fergus Henderson <fjh@cs.mu.OZ.AU> wrote:
>>David R Tribble <david@tribble.com> writes:
>>>...the program
>>>containing the C and C++ functions must be a C++ program (having
>>>a main() compiled as C++).
>>
>>This is implementation-dependent
...
>>Unfortunately, despite the increasing importance of multi-language
>>programming, the C and C++ standards do not address this issue.
>>So it's just a quality of implementation issue.
>
>I'm having a problem following how the conclusion in your
>last line is supported by those above it. That is, doesn't
>the C++ Standard describe C++ programs at some level?
>If so, then main is required (at least in hosted environments),
>and since it is a function that will be written in C++,
>then it follows that the C++ Standard describes it too.
Actually the standard says:
[basic.start.main] 3.6.1 Main function
1 A program shall contain a global function called main, which is the
designated start of the program. It is implementation-defined whether a
program in a freestanding environment is required to define a main
function. [Note: in a freestanding environment, start-up and termination
is implementation-defined; start-up contains the execution of constructors
for objects of namespace scope with static storage duration; termination
contains the execution of destructors for objects with static storage
duration.]
So it seems that if main() is in another language, the C++ says that it is
up to the implementation to decide what to do with global data
construction/destruction. (If one interprets it as if main() is in another
language, it is a "freestanding environment".)
Whatever, I think it will not suffice for the next C++ standards version.
Hans Aberg * Anti-spam: remove "remove." from email address.
* Email: Hans Aberg <remove.haberg@member.ams.org>
* Home Page: <http://www.matematik.su.se/~haberg/>
* AMS member listing: <http://www.ams.org/cml/>
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: David R Tribble <david@tribble.com>
Date: 2000/10/18 Raw View
Andrew J Robb wrote:
> Where I want to invoke methods on a class from within C (e.g. from
> Oracle Pro*C), I sidestep the issue by using function pointers to
> static methods.
>
> Example:
>
> header file, Cstruct.h
>
> #ifndef CSTRUCT_INCLUDED
> #define CSTRUCT_INCLUDED
>
> /* declaration of a struct and a function type, shared by C and C++ */
> struct Cstruct;
> typedef void (*Method)(Cstruct *);
^
Type 'Method' is a pointer to an extern "C++" function if the header
is included in a C++ program, and is a pointer to an extern "C"
function if it's included in a C program; these are two incompatible
function pointer types.
> #ifdef __cplusplus
> // C++ definition of Cstruct
> // for brevity I shall defy convention and declare a static method
> // within a struct
> struct Cstruct
> {
> ....
> // static method that matches the function pointer, Method
> static void someMethod(Cstruct *);
> };
>
> extern "C" { // C++ declaration of C linkage
> #endif /*__cplusplus*/
>
> /* shared declaration of C function */
> void Cfunction(struct Cstruct *, Method);
>
> #ifdef __cplusplus
> } // extern "C"
> #endif
>
> #endif /*CSTRUCT_INCLUDED*/
>
> I can then pass a pointer to Cstruct, ptr, and a function pointer to
> Cstruct::someMethod to a C function, which then uses method(ptr):
>
> /* embedded C routine that calls C++ */
> #include "Cstruct.h"
> void Cfunction(struct Cstruct * ptr, Method method)
> {
> ....
> method(ptr);
^
> ....
> }
This call mixes incompatible pointer-to-extern-C++-function and
pointer-to-extern-C-function types.
Your idea is correct, but it's a little hard to get the syntax
and types exactly right. To force a function pointer to have the
right linkage, try this:
#ifdef __cplusplus
extern "C"
{
#endif
typedef void (*Method)(Cstruct *);
// Pointer to C function, in C and C++
#ifdef __cplusplus
}
#endif
--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: Steve Clamage <stephen.clamage@sun.com>
Date: 2000/10/19 Raw View
Hans Aberg wrote:
>
> So this yet another weakness of the C++ standard: It should not only tell
> that it is legal to have main in C, but also when the C++ data should be
> initialized.
But you never need to write main in C. If you have an existing main
in C that can't be compiled as C++, you can change its name to,
for example, C_main, and write a C++ main:
extern "C" int C_main(int, char**);
int main(int argc, char** argv) { return C_main(argc, argv); }
If C and C++ can be mixed at all on the platform, this technique
must always work.
It is common for implementations to allow main to be written in C,
or even in other languages, but I don't think the C++ standard
should require it. That requirement would make it difficult for
3rd-party compiler vendors to compete with platform vendors
that also supply compilers. (I don't need a disclaimer for that
viewpoint: I work for a platform vendor that sells compilers.)
Beyond that, C++ provides the language-linkage syntax as a hook
to allow mixed-language programming on implementations that
support it at all.
To specify details of support for languages other than C would
require the C++ standard to track other language standards.
Given the long time frames and independent schedules of language
standards, it would be difficult to remain relevent. For example,
consider Fortran: should compatibility with all 4 current standards
be required, or some subset of them? It's easy to say "Just the
latest one", but F95 is not as widespread as earlier versions. What
about languages (like Basic) having formal standards that no one
uses and informal, unpublished, de-facto standards?
Instead of trying to slay that dragon, I think it is better to leave
it as a market-driven issue.
--
Steve Clamage, stephen.clamage@sun.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: Pete Becker <petebecker@acm.org>
Date: 2000/10/19 Raw View
Fergus Henderson wrote:
>
> Pete Becker <petebecker@acm.org> writes:
>
> >Greg Comeau wrote:
> >>
> >> So how can it be implementation-defined that main can be in some
> >> other language?
> [...]
> >
> >I think Fergus' message muddled the issue a little. The C++ standard
> >says that main must be written in C++. It also talks about the effect of
> >'extern "C"'. with the result being that there's a chance that you can
> >intermix C++ code (which includes main) with functions labeled 'extern
> >"C"' and written in C.
>
> That's one reasonable interpretation. But as I have just explained
> in detail in another message, I think there are quite a few other
> reasonable interpretations.
>
> Note that your interpretation gives no guarantees.
> It only offers "a chance" that things might work.
> It would be equally valid to say that there's also
> "a chance" that you can intermix C++ code which does
> NOT include main() with functions labeled `extern "C"'
> and written in C.
>
Yes, that's what the rest of my message said.
--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Contributing Editor, C/C++ Users Journal (http://www.cuj.com)
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: 2000/10/19 Raw View
In article <39ED34CD.419E666F@localhost.localdomain>,
AJRobb@REMOVE.bigfoot.com.screaming.net wrote:
>> -- It is in fact easy to check if the C++ is initialized, even if main()
>> is in C; simply add some C++ global data:
...
>I would not propose that calling C++ from a C program should be supported by
>the standard.
You end up on this equation because it is a must, one has a program
written by somebody else in C (or Pascal, or ...), often a large one, and
one wants to let your program written in C++ to be called by that program.
Hans Aberg * Anti-spam: remove "remove." from email address.
* Email: Hans Aberg <remove.haberg@member.ams.org>
* Home Page: <http://www.matematik.su.se/~haberg/>
* AMS member listing: <http://www.ams.org/cml/>
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: 2000/10/13 Raw View
May I point out that not being able to call C++ from C hurts the use of
C++, because one cannot switch from C to C++ and expect that program to be
used as a library by a program written in C.
So therefore I think that either the C standard should be augmented to to
have a C++ style statement
extern "C" { ... };
where ... should be able to contain at least simple function calls.
Or the C++ standard should be augmented to have a statement
export "C" { ... };
where one can export some hooks for use with C.
Hans Aberg * Anti-spam: remove "remove." from email address.
* Email: Hans Aberg <remove.haberg@member.ams.org>
* Home Page: <http://www.matematik.su.se/~haberg/>
* AMS member listing: <http://www.ams.org/cml/>
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: prj@po.cwru.edu (Paul Jarc)
Date: 2000/10/13 Raw View
remove.haberg@matematik.su.se (Hans Aberg) writes:
> Or the C++ standard should be augmented to have a statement
> export "C" { ... };
> where one can export some hooks for use with C.
This is already the case, with extern "C", AIUI. extern "C" means
that the entity being declared, regardless of what language it's
implemented in, has C-style linkage, so it's accessible from C.
paul
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: "Victor Bazarov" <vAbazarov@dAnai.com>
Date: 2000/10/13 Raw View
"Hans Aberg" <remove.haberg@matematik.su.se> wrote...
> May I point out that not being able to call C++ from C hurts the use
of
> C++, because one cannot switch from C to C++ and expect that program
to be
> used as a library by a program written in C.
I think that inability to call C++ from <language> is not
deficiency of C++ but rather of <language>.
>
> So therefore I think that either the C standard should be augmented to
to
> have a C++ style statement
> extern "C" { ... };
> where ... should be able to contain at least simple function calls.
>
> Or the C++ standard should be augmented to have a statement
> export "C" { ... };
> where one can export some hooks for use with C.
So, what about other languages, like Smalltalk, FORTRAN, Pascal, etc.?
Do you propose to include all possible combinations of extern "??" in
C as well, or just extern "C++"? (BTW, C++ already has that, the linkage
statement has 'extern "language" ' form, not just 'extern "C" ') And,
do we need 'export "language" ' linkage specifier in C++? How do you
propose to implement such a thing? Should C++ Standard refer to the
FORTRAN Standard for that or shall that be implementation-defined?
Victor
--
Please remove capital A's from my address when replying by mail
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: Jim Hyslop <jim.hyslop@leitch.com>
Date: 2000/10/13 Raw View
In article
<remove.haberg-1310002038450001@du138-226.ppp.su-anst.tninet.se>,
remove.haberg@matematik.su.se (Hans Aberg) wrote:
> May I point out that not being able to call C++ from C hurts the use
> of
> C++, because one cannot switch from C to C++ and expect that program
> to be
> used as a library by a program written in C.
But you can call a C++ program from a C program. You just have to go
through some major contortions to get the C++ name sometimes.
> So therefore I think that either the C standard should be augmented to
> to
> have a C++ style statement
> extern "C" { ... };
> where ... should be able to contain at least simple function calls.
Well, I guess the forum for that suggestion would be comp.std.c :-)
> Or the C++ standard should be augmented to have a statement
> export "C" { ... };
> where one can export some hooks for use with C.
extern "C" works just fine for this.
// file: tcpp.cpp
#include <iostream>
extern "C"
{
void helloCPlusPlus()
{ std::cout << "Hello, C++ world!" << std::endl; }
}
// end file tcpp.cpp
// file: test.c
#include <stdio.h>
extern void helloCPlusPlus();
int main()
{
printf("Hello, C World!\n");
fflush(stdout);
helloCPlusPlus();
}
// end file test.c
The two files compile and link cleanly, and give the expected output:
Hello, C World!
Hello, C++ World!
--
Jim
This message was posted using plain text only. Any hyperlinks you may
see were added by other parties without my permission.
I do not endorse any products or services that may be hyperlinked to
this message.
Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: "Per Velschow" <per@velschow.com>
Date: 2000/10/14 Raw View
> So therefore I think that either the C standard should be augmented to to
> have a C++ style statement
> extern "C" { ... };
> where ... should be able to contain at least simple function calls.
Didn't you mean
extern "C++" {...}
?
So your idea is that you want the C compiler to link with name-mangled
functions from C++, right? I don't think that this would help much. Most C++
programs don't contain many truly global functions that would qualify to be
called from a C program. In C++ most functions are methods of classes or
they are contained inside a namespace. So if this should be useful, you
would have to introduce both the concept of classes and namespaces in the C
language. And... well... then it isn't really C anymore, is it?
> Or the C++ standard should be augmented to have a statement
> export "C" { ... };
> where one can export some hooks for use with C.
What would this export do that the existing extern "C" doesn't already do?
/Per
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: Barry Margolin <barmar@genuity.net>
Date: 2000/10/14 Raw View
In article <remove.haberg-1310002038450001@du138-226.ppp.su-anst.tninet.se>,
Hans Aberg <remove.haberg@matematik.su.se> wrote:
>May I point out that not being able to call C++ from C hurts the use of
>C++, because one cannot switch from C to C++ and expect that program to be
>used as a library by a program written in C.
This could be difficult to make work. C++ allows arbitrary code to be run
to initialize static variables, whereas C requires static initializers to
be constants, and there may be some additional bookkeeping that has to be
done at startup time (perhaps constructing virtual tables). Typically,
this is implemented in C++ by automatically creating an initialization
function that runs before main(), but this requires that a C++ compiler is
processing the source module containing main(). If main() is compiled by a
C compiler, it will set up the normal startup linkage, and when C++
functions get called none of the setup will have been done.
C++ doesn't really require that initialization be done this way, since it
only requires that this stuff be initialized before its first reference.
So it would be possible for every function defined in an extern "C" to
start up with a little code that checks whether initialization is
necessary. There could even be two entry points -- one with the unmangled
name that's used from C callers, and another with a mangled name for calls
from C++, and only the first would need the extra check.
--
Barry Margolin, barmar@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: 2000/10/14 Raw View
In article <m3em1k1rcc.fsf@multivac.student.cwru.edu>, prj@po.cwru.edu
(Paul Jarc) wrote:
>> Or the C++ standard should be augmented to have a statement
>> export "C" { ... };
>> where one can export some hooks for use with C.
>
>This is already the case, with extern "C", AIUI. extern "C" means
>that the entity being declared, regardless of what language it's
>implemented in, has C-style linkage, so it's accessible from C.
Right, I was blinded to the fact that the extern "C" clause only applies
to the linkage of the function declared and not in it.
<vAbazarov@dAnai.com> wrote:
>So, what about other languages, like Smalltalk, FORTRAN, Pascal, etc.?
>Do you propose to include all possible combinations of extern "??" in
>C as well, or just extern "C++"?
In fact this is quite common, not only with C++, but with C already. For
example, I program under MacOS that was originally written in Pascal, and
for that prupose MacOS C compilers have constructs that allow extern
Pascal linkage.
-- So I have already written a lot of functions with extern Pascal
linkage, but with intern C code. I simply did not think of the real
meaning of the C++ "extern" construct.
> (BTW, C++ already has that, the linkage
>statement has 'extern "language" ' form, not just 'extern "C" ')
So, as you point out, C++ already has a language construct which allows
language extensions. The C extern Pascal construct on my compiler looks
like
pascal aPascalFunction(...) { /* C Code */ }
If the C++ compiler does not have a Pascal extension, one must write
extern "C" { pascal aPascalFunction(...) { /* C++ Code */ } }
However, I have checked that my compiler now has
extern "Pascal" { aPascalFunction(...) { /* C++ Code */ } }
Note the difference in capitalization, the C "pascal" and the C++ "Pascal"
-- the compiler will complain if this is not exactly as written.
In article <8s7ot6$5qq$1@nnrp1.deja.com>, Jim Hyslop
<jim.hyslop@leitch.com> wrote:
>But you can call a C++ program from a C program. You just have to go
>through some major contortions to get the C++ name sometimes.
...
>// file: tcpp.cpp
>#include <iostream>
>
>extern "C"
>{
> void helloCPlusPlus()
> { std::cout << "Hello, C++ world!" << std::endl; }
>}
>// end file tcpp.cpp
>
>// file: test.c
>#include <stdio.h>
>
>extern void helloCPlusPlus();
>
>int main()
>{
> printf("Hello, C World!\n");
> fflush(stdout);
> helloCPlusPlus();
>}
>// end file test.c
>
>The two files compile and link cleanly, and give the expected output:
>Hello, C World!
>Hello, C++ World!
In fact this short example makes me very happy, because now I can switch
(I hope), extending Hugs (and perhaps Bison, too), which otherwise are
entirely written in C, using C++ instead.
-- The problem with the C programming, apart from that it is slow, is that
one tends to get lots of statically allocated arrays with the potential of
breaking if say a string becomes too long or something.
Hans Aberg * Anti-spam: remove "remove." from email address.
* Email: Hans Aberg <remove.haberg@member.ams.org>
* Home Page: <http://www.matematik.su.se/~haberg/>
* AMS member listing: <http://www.ams.org/cml/>
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]