C++ callback function passed to a C program

E

Eric Entressangle

Hi all,

is there any trouble setting an C++ static class method as callback
function for a C program or library ?

Thanks
 
R

Rolf Magnus

Eric said:
Hi all,

is there any trouble setting an C++ static class method as callback
function for a C program or library ?

Yes. The function will have C++ calling conventions, but be called using
C calling conventions. An some (many?) compilers, they are both the
same, but if they differ, it won't work. For maximum portability, you
should only use extern "C" functions for that, which is of course not
possible for member functions, even if static.
 
A

Alf P. Steinbach

Yes. The function will have C++ calling conventions, but be called using
C calling conventions. An some (many?) compilers, they are both the
same, but if they differ, it won't work. For maximum portability, you
should only use extern "C" functions for that, which is of course not
possible for member functions, even if static.

Using an 'extern "C"' function doesn't buy additional portability... ;-)

Reason: neither C nor C++ defines the machine-level calling convention,
nor name-mangling or other relevant things. With at least one of the
most used C and C++ compilers 'extern "C"' has _no_ effect on the
calling convention whatsoever. What it does influence with that
compiler is the name mangling, i.e. linkage compatibility: the compiler
trusts you to know what you're doing, since this spec removes type
information (e.g. name mangling) in order to be linkage-compatible
with C.

The main assumption for the callback problem is calling convention
compatibility, and linkage compatibility doesn't enter the picture, but
the details of the calling convention compatibility depends on the
compilers, and one should not assume that 'extern "C"' will influence
calling conventions, data type compatibility, or any such thing.
 
A

Alf P. Steinbach

I'm aware of that.

Then you should draw the logical conclusions from that,



[Silly and longish irrelevant quoting of the standard elided]
From the standard's POV,
POV?


those things [calling convention, data types etc.] are all part
of the linkage.

Even different versions of the same C++ compiler can produce
incompatible object code, in full agreement with the standard.
So in other words, what you write is not correct.


Anyway, what would you gain if your compiler use the correct naming for
the functions for calling them from C, if the data types aren't
compatible or the parameters are passed differently?

You'd have to ask Kernighan and Ritchie about that... For in C you can
have (or at least could have) incompatibility between calling code
and called code even within the same compilation unit; hence the tendency
of C programmers to write "int main(void)", because simply leaving out the
argument list for a function would match any signature. When C++ is
interfaced to C there is no way the C++ standard can compensate, and so
it does not even try.

On a more practical level it's _your_ job to make sure that everyhing
matches between call and called function.

Achieving linking is just one of many considerations, and furthermore,
is not relevant to using a C++ function as a callback.
 
R

Rolf Magnus

Alf said:
I'm aware of that.

Then you should draw the logical conclusions from that,



[Silly and longish irrelevant quoting of the standard elided]
From the standard's POV,

POV?

Point Of View
those things [calling convention, data types etc.] are all part
of the linkage.

Even different versions of the same C++ compiler can produce
incompatible object code, in full agreement with the standard.
So in other words, what you write is not correct.

But the part of the standard I quoted just says that.
You'd have to ask Kernighan and Ritchie about that... For in C you
can have (or at least could have) incompatibility between calling code
and called code even within the same compilation unit; hence the
tendency of C programmers to write "int main(void)", because simply
leaving out the argument list for a function would match any
signature.

AFAIK, this is due to historical reasons. In C99, it's not true anymore.
When C++ is interfaced to C there is no way the C++ standard can
compensate, and so it does not even try.

Well, it doesn't say how the linkage looks like, but it says that the
compiler _must_ offer C linkage. Most C++ compilers also understand C
or are bundled with a C compiler, and I would be quite surprised if
they wouldn't just make their C linkage compatible with the C compiler.
On a more practical level it's _your_ job to make sure that everyhing
matches between call and called function.

Well, it's "my" job to make sure that the compilers agree about their C
linkage style.
Achieving linking is just one of many considerations, and furthermore,
is not relevant to using a C++ function as a callback.

Look again at the OP's question. He asked about static members as
callback for a C program or library. And so it definitely is relevant.
That was my point anyway. I just answered that making the callback
function extern "C" is the most portable solution. Do you disagree
about that?
 
A

Alf P. Steinbach

Alf said:
Reason: neither C nor C++ defines the machine-level calling
convention, nor name-mangling or other relevant things.

I'm aware of that.

Then you should draw the logical conclusions from that,



[Silly and longish irrelevant quoting of the standard elided]
From the standard's POV,

POV?

Point Of View
those things [calling convention, data types etc.] are all part
of the linkage.

Even different versions of the same C++ compiler can produce
incompatible object code, in full agreement with the standard.
So in other words, what you write is not correct.

But the part of the standard I quoted just says that.
???

You'd have to ask Kernighan and Ritchie about that... For in C you
can have (or at least could have) incompatibility between calling code
and called code even within the same compilation unit; hence the
tendency of C programmers to write "int main(void)", because simply
leaving out the argument list for a function would match any
signature.

AFAIK, this is due to historical reasons. In C99, it's not true anymore.

Keep in mind that the C++ standard stems from 1997, and that 1997 < 1999.


Well, it doesn't say how the linkage looks like, but it says that the
compiler _must_ offer C linkage. Most C++ compilers also understand C
or are bundled with a C compiler, and I would be quite surprised if
they wouldn't just make their C linkage compatible with the C compiler.

As a concrete example, Visual C++ supports a number of different
calling conventions such as "__stdcall" (which oldtimers like me think
of as Pascal) and "__cdecl" (which we think of as "C", purely because
of typical usage). If you decorate a function with 'extern "C"',
then (with this widely used compiler) that does _not_ affect the
calling convention. It affects only the external name the linker sees
(wrt. to the standard there's not necessarily a linker involved, but
this scheme is, as far as I know, completely standard-conforming.)

The crux is that there's no such thing as "the" C compiler.

There are a number of different C compilers, and even using just one
compiler you can compile functions that look the same to the linker
(and so, no amount of fiddling in C++ can guarantee compatibility) but
which have different calling conventions, different sizes of int, or
whatever.



Well, it's "my" job to make sure that the compilers agree about their C
linkage style.
Yep.



Look again at the OP's question. He asked about static members as
callback for a C program or library. And so it definitely is relevant.
That was my point anyway. I just answered that making the callback
function extern "C" is the most portable solution. Do you disagree
about that?

Yep.
 
R

Rolf Magnus

Alf said:

I can repeat that quote again, though I don't know why you don't just
read it in my previous posting. So again, I said:
those things [calling convention, data types etc.] are all part
of the linkage.

And you said:

to which I agree, but not to:

I quoted the following sentence from the standard:

All function types, function names and variable names have a language
linkage. [Note: Some of the properties associated with an entity with
language linkage may be associated with a particular form of
representing names of objects and functions with external linkage, or
with a particular calling convention, etc. ]

It says that "a particular calling convetion, etc." is no less part of
the "language linkage" than "a particular form of representing names of
objects and functions with external linkage". That's what I said above
and you claimed to be "not correct".

Besides that, of course the code is not compatible with every C
compiler, but from what I read from the standard (Every implementation
shall provide for linkage to functions written in the C programming
language, "C", and linkage to C++ functions, "C++".), there must be at
least one C compiler that it's compatible with. How else would the
compiler be able to "provide linkage to functions written in the C
programming language"?
Keep in mind that the C++ standard stems from 1997, and that 1997 <
1999.

What does that have to do with each other?
As a concrete example, Visual C++ supports a number of different
calling conventions such as "__stdcall" (which oldtimers like me think
of as Pascal) and "__cdecl" (which we think of as "C", purely because
of typical usage). If you decorate a function with 'extern "C"',
then (with this widely used compiler) that does _not_ affect the
calling convention. It affects only the external name the linker sees
(wrt. to the standard there's not necessarily a linker involved, but
this scheme is, as far as I know, completely standard-conforming.)

The crux is that there's no such thing as "the" C compiler.

Yes, that seems to be a quality-of-implementation issue. But as I said,
I'd expect from a C++ compiler that is bundled with a C compiler that
by default both use the same C "language linkage", including calling
conventions.
There are a number of different C compilers, and even using just one
compiler you can compile functions that look the same to the linker
(and so, no amount of fiddling in C++ can guarantee compatibility) but
which have different calling conventions, different sizes of int, or
whatever.

Yes. What's your point?

Ok, so what would be more portable then?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top