473,703 Members | 2,324 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Static linkage and extern "C"

I have a question about mixing C and C++.

In a C++ translation unit, I want to define a function with internal
linkage and C calling convention. Here's a sample of what I want to do:

// main.cpp

// This is defined in a C module
extern "C" void fake_qsort(void *, std::size_t, std::size_t,
int (*compare)(cons t void*, const void*));

namespace {

int compare_func_(c onst void*, const void*);

} // anonymous namespace

int main()
{
foo bunch_of_foos[100];
// ... fill bunch_of_foos somehow

// Fake qsort has the same signature as std::qsort
// but is extern "C"
fake_qsort(&bun ch_of_foos, sizeof(bunch_of _foos), sizeof(foo),
compare_func_);

return 0;
}

int compare_func_(c onst void*, const void*)
{
// ...
}

In a C++ translation unit, compare_func_() will have C++ calling
convention by default, unless I explicitly declare it extern "C". And
the fake_qsort() function is expecting a function with C calling convention.

I know this is illegal:
extern "C" static int compare_func_(c onst void*, const void*);

And this *seems* to be legal:
namespace {
extern "C" int compare_func_(c onst void*, const void*);
} // anonymous namespace

But does it do what I want (give me a function with internal linkage but
C calling convention)?

What about this?
extern "C" {
static int compare_func_(c onst void*, const void*);
}

Or even this?
extern "C" {
namespace {
int compare_func_(c onst void*, const void*);
} // anonymous namespace
}

Mark

Oct 20 '05 #1
10 6183

"Mark A. Gibbs" <x_*********@ro gers.com_x> wrote in message
news:M-*************** *************** @rogers.com...
I have a question about mixing C and C++.

In a C++ translation unit, I want to define a function with internal
linkage and C calling convention. Here's a sample of what I want to do:

// main.cpp

// This is defined in a C module
extern "C" void fake_qsort(void *, std::size_t, std::size_t,
int (*compare)(cons t void*, const void*));
....... In a C++ translation unit, compare_func_() will have C++ calling
convention by default, unless I explicitly declare it extern "C". And the
fake_qsort() function is expecting a function with C calling convention.
Don't bother with that. extern "C" does not really specify calling
convention,
(it might) but does not specify *which* C calling convention :) if more then
one are available :)
extern "C" is practically only usefull to tell compiler not to mangle
symbols when
exporting functions, but if you do need to specify calling
convention you'll do it with implementation specific extensions anyway,
in which case you don't need extern "C". You have to use it if compiler
spits an error, which happens on some implementations .

I know this is illegal:
extern "C" static int compare_func_(c onst void*, const void*);

And this *seems* to be legal:
namespace {
extern "C" int compare_func_(c onst void*, const void*);
} // anonymous namespace

But does it do what I want (give me a function with internal linkage but C
calling convention)?
No. extern "C" function's can't be overloaded, neither namespace affects
anything .You get exactly the same symbol with or without namespace.

What about this?
extern "C" {
static int compare_func_(c onst void*, const void*);
}
It's an error, logical if you want.
Or even this?
extern "C" {
namespace {
int compare_func_(c onst void*, const void*);
} // anonymous namespace
}


Same thing . you want to export function name and to hide it in same time :)
This simply shows that extern "C" wants to do two things with one blow,
but fails both. :)
You need specifier both for calling convention and for name mangling
in real implementations .:)
So just drop extern "C" and if it works, ok, let it be, and #ifdef
implementations
where that is forced. :)
Final word, is that compiler might use different calling convention when
calling C++ and different when calling C, in which case extern "C" does
help, but that is nothing that can be fixed with switch or two :)

Greetings, Bane.

Oct 20 '05 #2

"Branimir Maksimovic" <bm***@eunet.yu > wrote in message
news:dj******** **@news.eunet.y u...

Final word, is that compiler might use different calling convention when
calling C++ and different when calling C, in which case extern "C" does
help, but that is nothing that can be fixed with switch or two :)

can't

Oct 20 '05 #3

"Branimir Maksimovic" <bm***@eunet.yu > wrote in message
news:dj******** **@news.eunet.y u...

"Branimir Maksimovic" <bm***@eunet.yu > wrote in message
news:dj******** **@news.eunet.y u...
What about this?
extern "C" {
static int compare_func_(c onst void*, const void*);
}


It's an error, logical if you want.


But not compiler error. It declares C function with internal linkage!

Gosh, one learns something new every day.


So this is the case when
namespace {
void f();
}

can't replace:

static void f();

Oct 20 '05 #4

"Branimir Maksimovic" <bm***@eunet.yu > wrote in message
news:dj******** **@news.eunet.y u...
What about this?
extern "C" {
static int compare_func_(c onst void*, const void*);
}


It's an error, logical if you want.


But not compiler error. It declares C function with internal linkage!

Gosh, one learns something new every day.

Oct 20 '05 #5
In article <dj**********@n ews.eunet.yu>,
Branimir Maksimovic <bm***@eunet.yu > wrote:
"Branimir Maksimovic" <bm***@eunet.yu > wrote in message
news:dj******* ***@news.eunet. yu...
"Branimir Maksimovic" <bm***@eunet.yu > wrote in message
news:dj******** **@news.eunet.y u...
What about this?
extern "C" {
static int compare_func_(c onst void*, const void*);
}

It's an error, logical if you want.


But not compiler error. It declares C function with internal linkage!

Gosh, one learns something new every day.


So this is the case when
namespace {
void f();
}

can't replace:

static void f();


Say again?
--
Greg Comeau / Celebrating 20 years of Comeauity!
Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
Oct 20 '05 #6

Branimir Maksimovic wrote:
Don't bother with that. extern "C" does not really specify calling
convention,
(it might) but does not specify *which* C calling convention :) if more then
one are available :)
extern "C" is practically only usefull to tell compiler not to mangle
symbols when
exporting functions, but if you do need to specify calling
convention you'll do it with implementation specific extensions anyway,
in which case you don't need extern "C". You have to use it if compiler
spits an error, which happens on some implementations .
I'm a little confused. "Linkage-specification" does not mean the same
thing as "calling convention"? Or is the linkage specification just a
part of the calling convention (or is the calling convention just a part
of the linkage specification)? The standard seems to tell me that a
linkage-specification includes a calling convention (among other things,
in 7.5.1).

And if linkage specification is not the same as calling convention,
doesn't that mean that for a given a compiler, the calling convention
used for C and C++ must be the same (otherwise you couldn't mix C and
C++ code)?

And if the calling convention is the same for C and C++ functions, then
why are these two function pointers different?

extern "C" void (*pf_c)(void);
extern "C++" void (*pf_cpp)(void) ;

(If I'm reading the standard right, there is a difference between the
two, and name mangling doesn't matter to function pointers.)
I know this is illegal:
extern "C" static int compare_func_(c onst void*, const void*);

And this *seems* to be legal:
namespace {
extern "C" int compare_func_(c onst void*, const void*);
} // anonymous namespace

But does it do what I want (give me a function with internal linkage but C
calling convention)?

No. extern "C" function's can't be overloaded, neither namespace affects
anything .You get exactly the same symbol with or without namespace.


I don't see what that has to do with overloading functions. And I don't
see what you're saying about getting the same symbol with or without the
namespace.

The way I see it is that this...

void foo()
{
}

.... defines a function that is externally visible with C++ linkage (when
compiled in C++). This...

namespace {
void foo()
{
}
} // anonymous namespace

.... defines a function that is not externally visible with C++ linkage.
This...

extern "C" void foo()
{
}

.... defines a function that is externally visible with C linkage. So
logically, this...

namespace {
extern "C" void foo()
{
}
} // anonymous namespace

.... should define a function that is not externally visible with C
linkage. No?
Same thing . you want to export function name and to hide it in same time :)
This simply shows that extern "C" wants to do two things with one blow,
but fails both. :)
'extern "C"' doesn't necessarily export the function (if I'm reading
this right). It would get exported anyway by default. 'extern
"anything"' tells the compiler/linker the calling convention (for
functions), and the format for the names of variables or functions with
external linkage, among other things. To me that implies that you should
be able to create 'extern "anything"' with *internal* linkage. It's
functionally the same thing as something with external linkage, except
the symbols aren't externally visible.
You need specifier both for calling convention and for name mangling
in real implementations .:)
So just drop extern "C" and if it works, ok, let it be, and #ifdef
implementations
where that is forced. :)
Final word, is that compiler might use different calling convention when
calling C++ and different when calling C, in which case extern "C" does
help, but that is nothing that can be fixed with switch or two :)


So... there is no difference between 'extern "C"' and 'extern "C++"' for
calling conventions, but there might be. And I don't need the 'extern
"C"' linkage specifier, but I might. And if I do, I really don't,
because I can use compiler settings to make it all go away.

All that sounds a little evasive and silly. Either it's necessary or
it's not, and if it is, then the question is still how to do it. If it
makes no difference on most implementations , great, but if I can write
one set of code that works (or at least that's legal C++, then we can
deal with broken compilers), without having to use conditional
compilation, then that seems to be the way to go.

Mark

Oct 20 '05 #7
Mark A. Gibbs wrote:
Branimir Maksimovic wrote:
Don't bother with that. extern "C" does not really specify calling
convention,
(it might) but does not specify *which* C calling convention :) if more then
one are available :)
extern "C" is practically only usefull to tell compiler not to mangle
symbols when
exporting functions, but if you do need to specify calling
convention you'll do it with implementation specific extensions anyway,
in which case you don't need extern "C". You have to use it if compiler
spits an error, which happens on some implementations .
I'm a little confused. "Linkage-specification" does not mean the same
thing as "calling convention"?


No. calling convention is part of linkage specification.

Or is the linkage specification just a part of the calling convention (or is the calling convention just a part
of the linkage specification)?
The opposite.

The standard seems to tell me that a linkage-specification includes a calling convention (among other things,
in 7.5.1).
Yes.

And if linkage specification is not the same as calling convention,
doesn't that mean that for a given a compiler, the calling convention
used for C and C++ must be the same (otherwise you couldn't mix C and
C++ code)?
No. calling convention should be there in linkage specification.
Problem is that extern "C" assumes only one possible calling
convention.It is simply not descriptive enough.

(If I'm reading the standard right, there is a difference between the
two, and name mangling doesn't matter to function pointers.)
I know this is illegal:
extern "C" static int compare_func_(c onst void*, const void*);

And this *seems* to be legal:
namespace {
extern "C" int compare_func_(c onst void*, const void*);
} // anonymous namespace

But does it do what I want (give me a function with internal linkage but C
calling convention)?

No. extern "C" function's can't be overloaded, neither namespace affects
anything .You get exactly the same symbol with or without namespace.


I don't see what that has to do with overloading functions.


Overloaded funcions have different symbols.

And I don't see what you're saying about getting the same symbol with or without the
namespace.
well, linker searches for symbols in object files.
if you write namespace One{ void f(){} } namespace Two { void f(){} }
you get two different functions.
but
namespace One { extern "C" void f(){} }
namespace Two { extern "C" void f(){} }
refer to same function "f" and you'll get same symbol for both
of them which produces linker error.
So namespaces does not affect extern "C" at all.

The way I see it is that this...

void foo()
{
}

... defines a function that is externally visible with C++ linkage (when
compiled in C++). This...

namespace {
void foo()
{
}
} // anonymous namespace

... defines a function that is not externally visible with C++ linkage.
No. it defines foo with external linkage. anonymous namespace simply
generates unique identifier , which is unkown.
you need "static" to specify internal linkage.
This...

extern "C" void foo()
{
}

... defines a function that is externally visible with C linkage. So
logically, this...

namespace {
extern "C" void foo()
{
}
} // anonymous namespace

... should define a function that is not externally visible with C
linkage. No?
No. namespaces does not affect linkage nor extern "C" symbols.
Same thing . you want to export function name and to hide it in same time :)
This simply shows that extern "C" wants to do two things with one blow,
but fails both. :)
'extern "C"' doesn't necessarily export the function (if I'm reading
this right). It would get exported anyway by default. 'extern
"anything"' tells the compiler/linker the calling convention (for
functions), and the format for the names of variables or functions with
external linkage, among other things.


No only two defined things are extern "C" for C linkage
and extern "C++" for C++ linkage, other literals can be
anything to implementation.

To me that implies that you should be able to create 'extern "anything"' with *internal* linkage.
Problem is that that keyword "extern " is used to specify external
linkage. Therefore you need extern "C" { static void f(); }
to specify internal linkage.

It's functionally the same thing as something with external linkage, except
the symbols aren't externally visible.
Or there are non of them. function with internal linkage does not need
symbol at all.
You need specifier both for calling convention and for name mangling
in real implementations .:)
So just drop extern "C" and if it works, ok, let it be, and #ifdef
implementations
where that is forced. :)
Final word, is that compiler might use different calling convention when
calling C++ and different when calling C, in which case extern "C" does
help, but that is nothing that can be fixed with switch or two :)


So... there is no difference between 'extern "C"' and 'extern "C++"' for
calling conventions, but there might be. And I don't need the 'extern
"C"' linkage specifier, but I might. And if I do, I really don't,
because I can use compiler settings to make it all go away.

All that sounds a little evasive and silly. Either it's necessary or
it's not, and if it is, then the question is still how to do it. If it
makes no difference on most implementations , great, but if I can write
one set of code that works (or at least that's legal C++, then we can
deal with broken compilers), without having to use conditional
compilation, then that seems to be the way to go.


Problem is that extern "C" is not guaranteed too work even if
compiles and links ok. You must know which calling convention
library you call(or calling code) use.
And if compiler does not use *that* calling convention
even if you specify extern "C", then you have to do non portable
stuff anyway.
I didn;t saw any compiler that use something like
extern "mangle_this_wa y_and_call_that _way_thing",
,rather, extern "C" is used to declare/define C function
within C++ code.
Strange enough it is not defined how to specify linking
with other C++ compiler, but it is assumed you can link with
C compiler :)

Greetings, Bane.

Oct 20 '05 #8
Branimir Maksimovic wrote:
Problem is that that keyword "extern " is used to specify external
linkage. Therefore you need extern "C" { static void f(); }
to specify internal linkage.


I thought you said that was illegal. If it's legal, and if it creates a
static extern "C" function, then that's what I need. Is that legal, and
is that what it's supposed to do?

Mark

Oct 20 '05 #9

Mark A. Gibbs wrote:
Branimir Maksimovic wrote:
Problem is that that keyword "extern " is used to specify external
linkage. Therefore you need extern "C" { static void f(); }
to specify internal linkage.
I thought you said that was illegal.


Oh, I corrected that in follow up post to myself :)

If it's legal, and if it creates a static extern "C" function, then that's what I need.
Yes.

Is that legal, and is that what it's supposed to do?


Of course, yes.

Greetings, Bane.

Oct 20 '05 #10

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

Similar topics

29
4395
by: Alexander Mahr | last post by:
Dear Newsgroup, I'm somehow confused with the usage of the static keyword. I can see two function of the keyword static in conjunction with a data member of a class. 1. The data member reffers in all objects of this class to the same data Or in other word by using the static keyword all objects of one class can share data. (This is what I want)
4
1534
by: Pat | last post by:
I would like to know what is the meaning of : static vector<int> v; What is the difference with: vector<int> v;
4
4754
by: kk_oop | last post by:
Hi. I need to write a C++ callback function and register it with a C program. I've read that this can be done if the callback function is a static method. I've also read that I should use a global function with the extern "C" prefix. I was leaning toward using the static method approach until I saw a posting that said compatibility between static C++ functions and C is not guaranteed in the respective language standards. This made me...
5
8905
by: Jon E. Scott | last post by:
I'm a little confused with "static" methods and how to access other unstatic methods. I'm a little new to C#. I'm testing a callback routine within a DLL and the callback function returns a string as one of the arguments. As shown below, I have no problems showing the string in the Report() method in a messagebox or console window, but how does one access a memo or label on a form from a static method? I want to throw the strings from...
1
1569
by: Alok Kumar | last post by:
a.cxx extern int b(); static int a(); int main() { b(); return a(); } static int a(){return 1;};
14
6016
by: Jess | last post by:
Hello, I learned that there are five kinds of static objects, namely 1. global objects 2. object defined in namespace scope 3. object declared static instead classes 4. objects declared static inside functions (i.e. local static objects) 5. objects declared at file scope.
0
8761
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9123
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9017
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
1
6594
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5923
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4434
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3125
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2462
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2070
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.