473,406 Members | 2,377 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

extern "C" in library header


I debated whether this belongs in comp.lang.c++, and finally decided
that it belongs here, because it really is a C question...

Suppose I have a perfectly friendly, harmless library, libfoo,
that presents a single function declared:
int foo_function(int x);

The world is simple and all the small creatures rejoice in
its simplicity.

Along comes the evil crumudgeon from the neighboing
kingdom who says: your library is not useable by my
people, and we will declare war on you!

Wishing to avert a catastrophe, we sully our beautiful
header somewhat by adding the tatoo of the beast:
#ifdef __cplusplus
extern "C" {
namespace foo {
#endif
and matching closing braces.

For several years, there is peace in the two
kingdoms.

One day, a young prince of the neighboring kingdom
decides that: foo::foo_function( x ) has redundant
foo, and recognizing that his kingdom still has
enough political clout, he declares that all implementations
of libfoo must provide a less redundant interface. And
so our glorious header is disfigured again and ends
up looking like:

#ifndef FOO_HDR
#define FOO_HDR 1

#ifdef __cplusplus
extern "C" {
namespace foo {
#endif /* __cplusplus */

int foo_function(int x);

#ifdef __cplusplus
int function( int x ) { return foo_function( x ); }
} /* namespace foo */
} /* extern "C" */
#endif /* __cplusplus */
#endif /* FOO_HDR */
The questions are:
1) Given that libfoo is a C library, and that foo.h is a
C header file, I find the above code somewhat
hideous. However, it does seem to provide a
fairly clean interface to the C++ programmer.
Is there anything there that will burn my C code?

2) Given that the final #ifdef __cpluplus block
is going to have to define functions for everything
in the library...is it even worth the hassle? After
all, the only thing the evil prince will gain is
the ability to use" foo::function" instead of
"foo::foo_function". But his foo namespace
is still cluttered. I find the definitions in the
header to be a heinous kludge, but as far as
I can tell, it is an accepted technique in that
not-so-far-away land that lies beyond the
water cooler. What think you?

--
William Pursell

Jun 29 '07 #1
17 3748
William Pursell said:

<snip>
>
The questions are:
1) Given that libfoo is a C library, and that foo.h is a
C header file, I find the above code somewhat
hideous.
Likewise.
However, it does seem to provide a
fairly clean interface to the C++ programmer.
So would a flamethrower.

My own preferred strategy is based on the following reasoning:

1) this is a C header, so it'll follow C rules, ONLY.
2) if C++ people want to use it, great! If not, who cares?
3) if they need to wrap another header around it, that's fine
by me, but I ain't changing this one.

<snip>
I find the definitions in the
header to be a heinous kludge, but as far as
I can tell, it is an accepted technique in that
not-so-far-away land that lies beyond the
water cooler. What think you?
I think C++ people have perfectly good techniques for dealing with C
libraries that do not involve modifying those libraries or their
associated headers. And if they haven't, they're not as good at code
re-use as they fondly imagine.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 29 '07 #2
On 2007-06-29, Richard Heathfield <rj*@see.sig.invalidwrote:
William Pursell said:
>I find the definitions in the
header to be a heinous kludge, but as far as
I can tell, it is an accepted technique in that
not-so-far-away land that lies beyond the
water cooler. What think you?

I think C++ people have perfectly good techniques for dealing with C
libraries that do not involve modifying those libraries or their
associated headers. And if they haven't, they're not as good at code
re-use as they fondly imagine.
I totally agree, and this wrapping of a 'namespace' around the C
header file is utterly pointless. Worse than that, it's harmful and
misleading.

In the C code the function will be called foo_function regardless of
what 'namespace' the C++ code has pretended that it is in. If the C++
code has a problem with name clashes, then this kludge is not going to
help. Either the C++ code has other functions supposedly called
foo_function which the C++ compiler has mangled into different
namespaces so they don't clash, or it has other extern "C" functions
which really are called foo_function and even if pretending they are
not can be achieved at compile time for the C++ code, it's not going
to be possible to get it to link with all the conflicting definitions
of foo_function.
Jun 29 '07 #3
William Pursell <bi**********@gmail.comwrote:
#ifndef FOO_HDR
#define FOO_HDR 1

#ifdef __cplusplus
extern "C" {
namespace foo {
#endif /* __cplusplus */

int foo_function(int x);

#ifdef __cplusplus
int function( int x ) { return foo_function( x ); }
} /* namespace foo */
} /* extern "C" */
#endif /* __cplusplus */
#endif /* FOO_HDR */
Bah.
The questions are:
1) Given that libfoo is a C library, and that foo.h is a
C header file, I find the above code somewhat
hideous.
That doesn't even begin to describe it.

Perhaps the best solution would be to have two headers, a foo.h for C,
and a foo.h++ for c++. A slight bit more work, but probably worth it.

Richard
Jun 29 '07 #4
On Fri, 29 Jun 2007 05:24:52 +0000, Richard Heathfield wrote:
>1) this is a C header, so it'll follow C rules, ONLY.
2) if C++ people want to use it, great! If not, who cares?
3) if they need to wrap another header around it, that's fine
by me, but I ain't changing this one.
You forget that C/C++ is the most common idiom in the region (look eg.
at job advertisements). Moreover, compared to the other macros many C
libraries put into their header files 'extern "C"' is really harmless.
--
Roland Pibinger
"The best software is simple, elegant, and full of drama" - Grady Booch
Jun 29 '07 #5

"William Pursell" <bi**********@gmail.comha scritto nel messaggio news:11**********************@k29g2000hsd.googlegr oups.com...
>
I debated whether this belongs in comp.lang.c++, and finally decided
that it belongs here, because it really is a C question...

Suppose I have a perfectly friendly, harmless library, libfoo,
that presents a single function declared:
int foo_function(int x);

The world is simple and all the small creatures rejoice in
its simplicity.

Along comes the evil crumudgeon from the neighboing
kingdom who says: your library is not useable by my
people, and we will declare war on you!

Wishing to avert a catastrophe, we sully our beautiful
header somewhat by adding the tatoo of the beast:
#ifdef __cplusplus
extern "C" {
namespace foo {
#endif
and matching closing braces.

For several years, there is peace in the two
kingdoms.

One day, a young prince of the neighboring kingdom
decides that: foo::foo_function( x ) has redundant
foo, and recognizing that his kingdom still has
enough political clout, he declares that all implementations
of libfoo must provide a less redundant interface. And
so our glorious header is disfigured again and ends
up looking like:

#ifndef FOO_HDR
#define FOO_HDR 1

#ifdef __cplusplus
extern "C" {
namespace foo {
#endif /* __cplusplus */

int foo_function(int x);

#ifdef __cplusplus
int function( int x ) { return foo_function( x ); }
} /* namespace foo */
} /* extern "C" */
#endif /* __cplusplus */
#endif /* FOO_HDR */
*cough* (fx:vomits)

Try this:
#ifdef __cplusplus
extern "C" {
#endif

int foo_function(int x);

#ifdef __cplusplus
} /* extern "C" */
#endif

And explain the foreign prince that foo_function is not a redundant
interface, and that if your people can use it, so can his people.
If his people want to follow their strange tradition of what they
call namespaces, that's their business. But you won't duplicate all
your functions because he doesn't like their name.
If he disagrees, add this to your header:

#ifdef __cplusplus
#include <cstdlib>
#include <cstdio>
int function(int x)
{
int result = foo_function(x);
#ifdef __DEATHSTATION
#if __DEATHSTATION >= 9000
std::free(std::stderr); // cool...
#else /* __DEATHSTATION < 9000 */
#error "You need to upgrade your machine to version 9000."
#endif
#else /* __DEATHSTATION not defined */
#error "This program uses features not available on your "\
"architecture."
#endif
return result;
}
#endif

And all of your problems will be solved, once and for all.
Jun 29 '07 #6

"Roland Pibinger" <rp*****@yahoo.comha scritto nel messaggio news:46***************@news.utanet.at...
On Fri, 29 Jun 2007 05:24:52 +0000, Richard Heathfield wrote:
>>1) this is a C header, so it'll follow C rules, ONLY.
2) if C++ people want to use it, great! If not, who cares?
3) if they need to wrap another header around it, that's fine
by me, but I ain't changing this one.

You forget that C/C++ is the most common idiom in the region (look eg.
at job advertisements).
But it is also used in other regions.
See http://www.catb.org/~esr/faqs/hacker-howto.html#skills1 and
read the first few words of the eighth paragraph...
Jun 29 '07 #7
rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
[...]
Perhaps the best solution would be to have two headers, a foo.h for C,
and a foo.h++ for c++. A slight bit more work, but probably worth it.
And good luck keeping them synchronized.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 29 '07 #8
Roland Pibinger said:
On Fri, 29 Jun 2007 05:24:52 +0000, Richard Heathfield wrote:
>>1) this is a C header, so it'll follow C rules, ONLY.
2) if C++ people want to use it, great! If not, who cares?
3) if they need to wrap another header around it, that's fine
by me, but I ain't changing this one.

You forget that C/C++ is the most common idiom in the region
No, it isn't the most common idiom in any region. Nor was it even
mentioned by the OP.
Moreover, compared to the other macros many C
libraries put into their header files 'extern "C"' is really harmless.
It's still not legal C, so it's off topic here.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 30 '07 #9
Keith Thompson said:
rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
[...]
>Perhaps the best solution would be to have two headers, a foo.h for
C, and a foo.h++ for c++. A slight bit more work, but probably worth
it.

And good luck keeping them synchronized.
Actually, that's pretty easy, if the <coughother header is simply a
wrapper, which #includes the C header.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 30 '07 #10
In article <hL******************************@bt.com>,
Richard Heathfield <rj*@see.sig.invalidwrote:
>Roland Pibinger said:
>Moreover, compared to the other macros many C
libraries put into their header files 'extern "C"' is really harmless.

It's still not legal C, so it's off topic here.
This:
--------
#ifdef __cplusplus
extern "C" {
#endif

/*stuff goes here*/

#ifdef __cplusplus
}
#endif
--------
is, I believe, acceptable to every known C implementation, and is
guaranteed to be legal C99, since C99 forbids C implementations from
#defining __cplusplus and as far as I know no known pre-C99 implementation
does so.

Keeping C headers C++-clean (by doing this and avoiding C++ keywords
in the header) is also a perfectly reasonable acknowledgement of the
syntactic similarity of C and C++, and allows C++ code to use the C
code (by #including the header and linking with the compiled code)
with minimal effort on the part of either programmer.
dave
(of course, the way the IDE I use at work gets confused when I use "class"
as an identifier in my C code (even when there's no C++ in sight) is
just inexcusable.)

--
Dave Vandervies dj******@csclub.uwaterloo.ca
This surprises me. The Dutch are not, contrary to our reputation, actually
rude, but we can sometimes be a bit... blunt. As a nation, we don't like
euphemism much. --Richard Bos in the scary devil monastery
Jun 30 '07 #11
Dave Vandervies said:
In article <hL******************************@bt.com>,
Richard Heathfield <rj*@see.sig.invalidwrote:
>>Roland Pibinger said:
>>Moreover, compared to the other macros many C
libraries put into their header files 'extern "C"' is really
harmless.

It's still not legal C, so it's off topic here.

This:
[reasonable code]
is, I believe, acceptable to every known C implementation, and is
guaranteed to be legal C99, since C99 forbids C implementations from
#defining __cplusplus and as far as I know no known pre-C99
#implementation
does so.
Well, if it will help, we can always write a pre-C99 implementation that
does. :-)
Keeping C headers C++-clean (by doing this and avoiding C++ keywords
in the header) is also a perfectly reasonable acknowledgement of the
syntactic similarity of C and C++, and allows C++ code to use the C
code (by #including the header and linking with the compiled code)
with minimal effort on the part of either programmer.
Maybe, maybe not. I still maintain that it's a C++ issue, not a C issue.
FTR, I make no effort whatsoever to make my headers C++-clean. If I
write C++ code that includes C headers, I just... well, what I do in
C++ is off-topic here, but suffice to say that it's really easy, and
doesn't involve tampering with the C headers.
(of course, the way the IDE I use at work gets confused when I use
"class" as an identifier in my C code (even when there's no C++ in
sight) is just inexcusable.)
Visual Studio, at a guess? It does the same for new, which I find mildly
distracting (on the rare occasions that I use VS), since I frequently
use 'new' as an identifier in constructors. (No, not that kind. C
constructors.)

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 30 '07 #12

"Dave Vandervies" <dj******@csclub.uwaterloo.caha scritto nel messaggio news:f6**********@rumours.uwaterloo.ca...
dave
(of course, the way the IDE I use at work gets confused when I use "class"
as an identifier in my C code (even when there's no C++ in sight) is
just inexcusable.)
What about MSVC which whenever I write "int main(" suggests me to
complete it with "const int&"?
Jul 1 '07 #13
Army1987 wrote:
"Dave Vandervies" <dj******@csclub.uwaterloo.caha scritto:
>(of course, the way the IDE I use at work gets confused when I
use "class" as an identifier in my C code (even when there's no
C++ in sight) is just inexcusable.)

What about MSVC which whenever I write "int main(" suggests me
to complete it with "const int&"?
If it does that when invoked as a C compiler (not C++) it is also
in violation of the syntax rules. Sounds like typical MS
sloppiness.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

Jul 1 '07 #14
CBFalconer said:
Army1987 wrote:
>"Dave Vandervies" <dj******@csclub.uwaterloo.caha scritto:
>>(of course, the way the IDE I use at work gets confused when I
use "class" as an identifier in my C code (even when there's no
C++ in sight) is just inexcusable.)

What about MSVC which whenever I write "int main(" suggests me
to complete it with "const int&"?

If it does that when invoked as a C compiler (not C++) it is also
in violation of the syntax rules.
He's talking about the editor's Intellisense capability, not the
compiler. The Microsoft C compiler is actually very good.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jul 1 '07 #15
Keith Thompson <ks***@mib.orgwrote:
rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
[...]
Perhaps the best solution would be to have two headers, a foo.h for C,
and a foo.h++ for c++. A slight bit more work, but probably worth it.

And good luck keeping them synchronized.
That's a matter of good program management, a.k.a., in this case,
planning ahead.

Richard
Jul 2 '07 #16
rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
Keith Thompson <ks***@mib.orgwrote:
>rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
[...]
Perhaps the best solution would be to have two headers, a foo.h for C,
and a foo.h++ for c++. A slight bit more work, but probably worth it.

And good luck keeping them synchronized.

That's a matter of good program management, a.k.a., in this case,
planning ahead.
A better matter of good program management would be to automatically
generate both headers from some common source, so they *can't* get out
of synch.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 2 '07 #17
Keith Thompson <ks***@mib.orgwrote:
rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
Keith Thompson <ks***@mib.orgwrote:
rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
[...]
Perhaps the best solution would be to have two headers, a foo.h for C,
and a foo.h++ for c++. A slight bit more work, but probably worth it.

And good luck keeping them synchronized.
That's a matter of good program management, a.k.a., in this case,
planning ahead.

A better matter of good program management would be to automatically
generate both headers from some common source, so they *can't* get out
of synch.
Depends. If this is a single header with a handful of functions, adding
another shackle to the compilation chain that wasn't there before is
probably only going to introduce more places for the process to go
wrong. If you are using a solid, flexible generation tool already to
generate the whole code base from dozens of templates, this is another
job well suited to it. In between, it's in between.

Richard
Jul 3 '07 #18

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: cppaddict | last post by:
In JNI header files generated by javah, what is going on with the 'extern "C"' which is inserted around the native method when "cplusplus" is defined. I would think you would only need extern...
4
by: cpptutor2000 | last post by:
Could some C++ guru help me please? I am trying to build an application using gcc 3.2.3, that has a some classes using functions defined in some C files in the same directory. If inside the C++...
13
by: RainBow | last post by:
Hi everyone, (Very Sorry, if this is the wrong group in which I am posting this query). Code snippet: //C library typedef int (*PFunc)(int* aArg); void call_c_foo(PFunc aPtrtoFunc) {
12
by: G Patel | last post by:
I've seen some code with extern modifiers in front of variables declared inside blocks. Are these purely definitions (no definition) or are they definitions with static duration but external...
0
by: Lei Jiang | last post by:
I have setup a .NET library in C++ language in VS.NET 2005 Beta1. I this project, I add some additional dependency to some C library. The header file of the C library has been marked as "extern...
5
by: jchludzinski | last post by:
I have 3 files (see below: a.h, w.c, ww.c). I would like to use a single x (declared somewhere) which would global to both compilation units: w.c & ww.c. No matter where I place the "extern"...
2
by: Bharath | last post by:
Hi All, I am a newbie to C++ and I'm trying to figure this out. Can you please help? We have 3rd party library that's written in c++. We don't have the source for it. ldd on that shared...
4
by: mimi | last post by:
The programmer indicates to the compiler that a function is written in a different programming language using a linkage directives.It is intuitive that extern "SomeLanguage" is used to declare...
3
by: Chris Cahoon | last post by:
Hello, I am trying to include a header file which was written in C, but my project is in C++. Even when I wrap the include statement or the entire header files with extern "C" (used according to...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.