The title says it all.
I can see the case where a function is to be called directly from C, the
name mangling will stuff this up.
But I can't see a reason why a template function can't be given extern
"C" linkage where it is to be assigned to a C function pointer.
Ian 22 5951
Ian <no***@nowhere.com> wrote in news:1122500290.491907@drone2-svc-
skyt.qsi.net.nz: The title says it all.
I can see the case where a function is to be called directly from C, the name mangling will stuff this up.
But I can't see a reason why a template function can't be given extern "C" linkage where it is to be assigned to a C function pointer.
Ian
Um... how would your C program (which doesn't know anything about
templates) include the header file where the template function is declared?
Keep in mind that a template function doesn't actually exist until it is
instantiated.... (not sure that "instantiated" is the right word....)
Andre Kostur wrote: [..] Keep in mind that a template function doesn't actually exist until it is instantiated.... (not sure that "instantiated" is the right word....)
It is the right word.
V
Andre Kostur wrote: Ian <no***@nowhere.com> wrote in news:1122500290.491907@drone2-svc- skyt.qsi.net.nz:
The title says it all.
I can see the case where a function is to be called directly from C, the name mangling will stuff this up.
But I can't see a reason why a template function can't be given extern "C" linkage where it is to be assigned to a C function pointer.
Ian
Um... how would your C program (which doesn't know anything about templates) include the header file where the template function is declared? Keep in mind that a template function doesn't actually exist until it is instantiated.... (not sure that "instantiated" is the right word....)
As I said, I understand why this case can't be, but the problem I had
involved setting up some callbacks for a C driver. The driver API has a
number of structs with function pointers for various callbacks.
So in this case, the C function pointers will be assigned in C++ code,
after the templates have been instantiated. the names are irrelevant to
the C code.
Ian
On Thu, 28 Jul 2005 11:08:17 +1200, Ian wrote: As I said, I understand why this case can't be, but the problem I had involved setting up some callbacks for a C driver. The driver API has a number of structs with function pointers for various callbacks.
So in this case, the C function pointers will be assigned in C++ code, after the templates have been instantiated. the names are irrelevant to the C code.
What problem are you running into? I'm not sure of your distinction of "C"
vs. "C++" functions, unless you mean stand-alone vs. class member
functions. Is your template creating a template function or a templated
class? If it's a class, then you can't use the address of the member
functions whether it's a template or not.
As far as I know, 'extern "C"' is irrelevant as far as function
pointers go.
If all else fails, create a standalone (non-template) function that calls
the template one, and set a pointer to it instead.
- Jay
Jay Nabonne wrote: On Thu, 28 Jul 2005 11:08:17 +1200, Ian wrote:
As I said, I understand why this case can't be, but the problem I had involved setting up some callbacks for a C driver. The driver API has a number of structs with function pointers for various callbacks.
So in this case, the C function pointers will be assigned in C++ code, after the templates have been instantiated. the names are irrelevant to the C code.
What problem are you running into? I'm not sure of your distinction of "C" vs. "C++" functions, unless you mean stand-alone vs. class member functions. Is your template creating a template function or a templated class? If it's a class, then you can't use the address of the member functions whether it's a template or not.
In an ideal world, I wanted something like:
extern "C" {
template <typename T> int bla() { return T().bla(); }
}
so I could set up the C struct thus:
template <typename T>
struct Fred : FredFromC
{
Fred() { fnPointer = bla<T>; }
};
Where fnPointer is a member of FredFromC.
As far as I know, 'extern "C"' is irrelevant as far as function pointers go.
That's just it, there is a difference and it is relevant.
Ian
On Thu, 28 Jul 2005 11:47:09 +1200, Ian wrote: In an ideal world, I wanted something like:
extern "C" { template <typename T> int bla() { return T().bla(); } }
so I could set up the C struct thus:
template <typename T> struct Fred : FredFromC { Fred() { fnPointer = bla<T>; } };
Where fnPointer is a member of FredFromC.
This compiles for me under Visual C++ 7.0 and gcc 3.2.3:
// Begin code
struct FredFromC
{
int (*fnPointer)();
};
template <typename T> int bla() { /*return T().bla();*/ return 0; }
template <typename T>
struct Fred : FredFromC
{
Fred() { fnPointer = bla<T>; }
};
Fred<int> myStruct;
// End code
It even works if I put 'extern "C"' around the "FredFromC" structure
definition.
Again, what is the problem that you're having (e.g. what is the error
message).
- Jay
Ian wrote: In an ideal world, I wanted something like:
extern "C" { template <typename T> int bla() { return T().bla(); } }
so I could set up the C struct thus:
template <typename T> struct Fred : FredFromC { Fred() { fnPointer = bla<T>; } };
Where fnPointer is a member of FredFromC.
And how is it going to be used?
V
Victor Bazarov wrote: Ian wrote:
In an ideal world, I wanted something like:
extern "C" { template <typename T> int bla() { return T().bla(); } }
so I could set up the C struct thus:
template <typename T> struct Fred : FredFromC { Fred() { fnPointer = bla<T>; } };
Where fnPointer is a member of FredFromC.
And how is it going to be used?
By the operating system as a callback into the driver. FredFromC is a
structure defined by the OS to be populated with callbacks for various
driver functions.
Ian
Jay Nabonne wrote: On Thu, 28 Jul 2005 11:47:09 +1200, Ian wrote:
In an ideal world, I wanted something like:
extern "C" { template <typename T> int bla() { return T().bla(); } }
so I could set up the C struct thus:
template <typename T> struct Fred : FredFromC { Fred() { fnPointer = bla<T>; } };
Where fnPointer is a member of FredFromC. Again, what is the problem that you're having (e.g. what is the error message).
If I compile the following (based on your example):
extern "C" {
struct FredFromC
{
int (*fnPointer)();
};
}
template <typename T> int bla() { return 0; }
template <typename T>
struct Fred : FredFromC
{
Fred() { fnPointer = bla<T>; }
};
int
main()
{
Fred<int> myStruct;
}
The compiler correctly warns:
"/tmp/x.cc", line 13: Warning (Anachronism): Assigning int(*)() to
extern "C" int(*)().
In this example, I can see no practical reason why bla() couldn't have
been declared as extern "C".
Ian
On Thu, 28 Jul 2005 12:38:08 +1200, Ian wrote: The compiler correctly warns:
"/tmp/x.cc", line 13: Warning (Anachronism): Assigning int(*)() to extern "C" int(*)().
In this example, I can see no practical reason why bla() couldn't have been declared as extern "C".
Ah, I see. A warning. Unfortunately, I can't coax any of the compilers I
have at my disposal to warn me about that, so I can't even begin to try to
figure out how to solve it (as I have no way to test).
I suppose this does no better:
template <typename T>
struct Fred : FredFromC
{
static int bla() { /*return T().bla();*/ return 0; }
Fred() { fnPointer = bla<T>; }
};
Good luck...
- Jay
On Thu, 28 Jul 2005 00:49:45 +0000, Jay Nabonne wrote: On Thu, 28 Jul 2005 12:38:08 +1200, Ian wrote:
template <typename T> struct Fred : FredFromC { static int bla() { /*return T().bla();*/ return 0; } Fred() { fnPointer = bla<T>; }
// Oops. I meant:
Fred() { fnPointer = bla; }
};
Good luck...
- Jay
Ian wrote: Victor Bazarov wrote: Ian wrote:
In an ideal world, I wanted something like:
extern "C" { template <typename T> int bla() { return T().bla(); } }
so I could set up the C struct thus:
template <typename T> struct Fred : FredFromC { Fred() { fnPointer = bla<T>; } };
Where fnPointer is a member of FredFromC.
And how is it going to be used? By the operating system as a callback into the driver. FredFromC is a structure defined by the OS to be populated with callbacks for various driver functions.
Sorry, that basically means nothing here. You should consider posting
the C code that calls whatever callbacks you are trying to define.
V
Victor Bazarov wrote: Ian wrote:
Victor Bazarov wrote:
Ian wrote:
In an ideal world, I wanted something like:
extern "C" { template <typename T> int bla() { return T().bla(); } }
so I could set up the C struct thus:
template <typename T> struct Fred : FredFromC { Fred() { fnPointer = bla<T>; } };
Where fnPointer is a member of FredFromC.
And how is it going to be used?
By the operating system as a callback into the driver. FredFromC is a structure defined by the OS to be populated with callbacks for various driver functions.
Sorry, that basically means nothing here. You should consider posting the C code that calls whatever callbacks you are trying to define.
It's part of an operating system and I don't have it.
The calling code is irrelevant to the original question. I'm still none
the wiser as to why template functions can't be given extern "C" linkage.
Apart form the mangled name, a template function is (well OK, can be) no
different than any other with the same signature:
#include <iostream>
template <typename T> void tem( int n ) { std::cout << n << std::endl; }
void normal( int n ) { std::cout << n*2 << std::endl; }
typedef void (*Fn)( int );
int
main()
{
Fn fn1 = &tem<int>;
Fn fn2 = &normal;
fn1( 2 );
fn2( 2 );
}
but we can't do
extern "C"{
template <typename T> void tem( int n ) {}
void normal( int n ) {}
typedef void (*Fn)( int );
}
Ian
Ian wrote: [..] The calling code is irrelevant to the original question. I'm still none the wiser as to why template functions can't be given extern "C" linkage.
(a) It doesn't make sense since there is no way to use templates
from C -- it just doesn't have that mechanism. To learn more on
"why" certain things the way they are, post to comp.std.c++, that
is the "why" newsgroup. We here talk mostly "how".
Apart form the mangled name, a template function is (well OK, can be) no different than any other with the same signature:
(b) I think you're a bit confused. There are no "template functions".
There are only "function templates". What you have here is
a template, not a function.
(c) Templates can have linkage, but they cannot have "C" linkage because
the Standard prohibits it in 14/4.
#include <iostream>
template <typename T> void tem( int n ) { std::cout << n << std::endl; } void normal( int n ) { std::cout << n*2 << std::endl; }
typedef void (*Fn)( int );
int main() { Fn fn1 = &tem<int>; Fn fn2 = &normal;
There is no need for '&' here, BTW fn1( 2 ); fn2( 2 ); }
but we can't do
extern "C"{ template <typename T> void tem( int n ) {} void normal( int n ) {}
typedef void (*Fn)( int ); }
Correct, we can't.
V
Victor Bazarov wrote: Ian wrote:
[..] The calling code is irrelevant to the original question. I'm still none the wiser as to why template functions can't be given extern "C" linkage.
(a) It doesn't make sense since there is no way to use templates from C -- it just doesn't have that mechanism. To learn more on "why" certain things the way they are, post to comp.std.c++, that is the "why" newsgroup. We here talk mostly "how".
A function template could be called indirectly through a function pointer.Apart form the mangled name, a template function is (well OK, can be) no different than any other with the same signature:
(b) I think you're a bit confused. There are no "template functions". There are only "function templates". What you have here is a template, not a function.
OK, I got the name the wrong way round, but I'm not confused.
(c) Templates can have linkage, but they cannot have "C" linkage because the Standard prohibits it in 14/4.
True, but it doesn't appear to say why.
Ian
* Ian: Victor Bazarov wrote: Ian wrote:
[..] The calling code is irrelevant to the original question. I'm still none the wiser as to why template functions can't be given extern "C" linkage.
(a) It doesn't make sense since there is no way to use templates from C -- it just doesn't have that mechanism. To learn more on "why" certain things the way they are, post to comp.std.c++, that is the "why" newsgroup. We here talk mostly "how". A function template could be called indirectly through a function pointer.
You don't need 'extern "C"' to do that. Apart form the mangled name, a template function is (well OK, can be) no different than any other with the same signature:
(b) I think you're a bit confused. There are no "template functions". There are only "function templates". What you have here is a template, not a function.
OK, I got the name the wrong way round, but I'm not confused.
I agree with Victor, you're a little bit confused here, probably because of
lack of knowledge of the practical stuff not mentioned in the standard. (c) Templates can have linkage, but they cannot have "C" linkage because the Standard prohibits it in 14/4. True, but it doesn't appear to say why.
Because "C" linkage is meant to be compatible with C (the same vendor's C
compiler), where _in practice_ function names have very simple ornamentation
in the object code -- the names that the linker sees. For example, 'foo'
in the source code will, with C linkage, typically end up as '_foo' in the
object code. There is nothing there to distinguish this foo from other
instantiations or other foo functions with different arguments. In short, C
does not support function name overloading. And a function template can be
regarded as an extreme case of overloading, a kind of ininite overloading.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Ian wrote: Victor Bazarov wrote: Ian wrote:
[..] The calling code is irrelevant to the original question. I'm still none the wiser as to why template functions can't be given extern "C" linkage.
(a) It doesn't make sense since there is no way to use templates from C -- it just doesn't have that mechanism. To learn more on "why" certain things the way they are, post to comp.std.c++, that is the "why" newsgroup. We here talk mostly "how". A function template could be called indirectly through a function pointer.
No, it cannot. Only an instantiation of it or a specialisation of it
can. Apart form the mangled name, a template function is (well OK, can be) no different than any other with the same signature:
(b) I think you're a bit confused. There are no "template functions". There are only "function templates". What you have here is a template, not a function.
OK, I got the name the wrong way round, but I'm not confused.
You hope... (c) Templates can have linkage, but they cannot have "C" linkage because the Standard prohibits it in 14/4. True, but it doesn't appear to say why.
Nor is it supposed to. That's what 'comp.std.c++' is for.
V
Alf P. Steinbach wrote: * Ian:
Victor Bazarov wrote:
Ian wrote:
[..] The calling code is irrelevant to the original question. I'm still none the wiser as to why template functions can't be given extern "C" linkage.
(a) It doesn't make sense since there is no way to use templates from C -- it just doesn't have that mechanism. To learn more on "why" certain things the way they are, post to comp.std.c++, that is the "why" newsgroup. We here talk mostly "how".
A function template could be called indirectly through a function pointer.
You don't need 'extern "C"' to do that.
We're going round in circles here, you do to assign an instantiation of
a function template to a extern "C' function pointer. I agree with Victor, you're a little bit confused here, probably because of lack of knowledge of the practical stuff not mentioned in the standard.
I've been doing the practical stuff since the early days of cfront
compilers, so I know quite a lot about what goes on under the hood. Because "C" linkage is meant to be compatible with C (the same vendor's C compiler), where _in practice_ function names have very simple ornamentation in the object code -- the names that the linker sees. For example, 'foo' in the source code will, with C linkage, typically end up as '_foo' in the object code. There is nothing there to distinguish this foo from other instantiations or other foo functions with different arguments. In short, C does not support function name overloading. And a function template can be regarded as an extreme case of overloading, a kind of ininite overloading.
That's why C++ uses name mangling. Which is probably why the standard
forbids function templates from having extern "C" linkage, as there is
no way for C to call a mangled function directly.
But it would still be nice to be able to assign an instantiation of a
function template to a extern "C' function pointer.
Ian
* Ian: * Alf P. Steinbach: * Ian: * Victor Bazarov: > * Ian: > > [..] > > The calling code is irrelevant to the original question. I'm still > > none the wiser as to why template functions can't be given extern "C" > > linkage. > > (a) It doesn't make sense since there is no way to use templates > from C -- it just doesn't have that mechanism. To learn more on > "why" certain things the way they are, post to comp.std.c++, that > is the "why" newsgroup. We here talk mostly "how".
A function template could be called indirectly through a function pointer.
You don't need 'extern "C"' to do that. We're going round in circles here, you do to assign an instantiation of a function template to a extern "C' function pointer.
Oh, sorry for jumping into the middle of a thread; I missed that bit of
context, if it was ever there.
Yes, it seems that's so.
But consider: to interface to C code everything about the function signature
is fixed, so all you have to do is to introduce an in-between 'extern "C"'
function calling your template code. I agree with Victor, you're a little bit confused here, probably because of lack of knowledge of the practical stuff not mentioned in the standard. I've been doing the practical stuff since the early days of cfront compilers, so I know quite a lot about what goes on under the hood. Because "C" linkage is meant to be compatible with C (the same vendor's C compiler), where _in practice_ function names have very simple ornamentation in the object code -- the names that the linker sees. For example, 'foo' in the source code will, with C linkage, typically end up as '_foo' in the object code. There is nothing there to distinguish this foo from other instantiations or other foo functions with different arguments. In short, C does not support function name overloading. And a function template can be regarded as an extreme case of overloading, a kind of ininite overloading.
That's why C++ uses name mangling. Which is probably why the standard forbids function templates from having extern "C" linkage, as there is no way for C to call a mangled function directly.
Right, you got it.
But it would still be nice to be able to assign an instantiation of a function template to a extern "C' function pointer.
See above, although many compilers such as MSVC already allow this, as an
extension, and although I agree that it would be nice and not only for
template functions, but also for static member functions. The problem here
is that C linkage seems to have been intended to address two different
practical aspects of linkage: name mangling, and machine code level calling
convention. For pointers the former is irrelevant, but the latter is still
relevant. In MSVC the calling convention is specified via a language
extension, not via the C/C++ linkage. And so MSVC can allow such pointers.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Alf P. Steinbach wrote: But it would still be nice to be able to assign an instantiation of a function template to a extern "C' function pointer.
See above, although many compilers such as MSVC already allow this, as an extension, and although I agree that it would be nice and not only for template functions, but also for static member functions. The problem here is that C linkage seems to have been intended to address two different practical aspects of linkage: name mangling, and machine code level calling convention. For pointers the former is irrelevant, but the latter is still relevant. In MSVC the calling convention is specified via a language extension, not via the C/C++ linkage. And so MSVC can allow such pointers.
This looks to be a good idea, unfortunately Sun's compiler is rather
pedantic in this area (maybe something to do the the author being the
C++ standard committee chairman!). I suppose I could disable the
warning and get on with life.
Cheers,
Ian
Ian wrote: The title says it all.
I can see the case where a function is to be called directly from C, the name mangling will stuff this up.
But I can't see a reason why a template function can't be given extern "C" linkage where it is to be assigned to a C function pointer.
Ian
C has no concept of multiple objects with the same name. It can't
even deal with simple function overloads, let alone templates.
Ian wrote: The title says it all.
I can't really tell from reading the rest of this thread what problem
you're trying to solve, but I'm assuming you have an pointer to an
extern "C" function and you want to assign a template function to it.
The portable way to do this is create an extern "C" wrapper function
around an instance of the template and take the address of it, but a
solution that works in practice is to just reinterpret_cast it to the
extern "C"'d type. I'd probably go with the wrapper function way though
since I don't like reinterpret_casts in my code.
I can see the case where a function is to be called directly from C, the name mangling will stuff this up.
But I can't see a reason why a template function can't be given extern "C" linkage where it is to be assigned to a C function pointer.
7.5/6 "At most one function with a particular name can have C language
linkage. Two declarations for a function with C language linkage with
the same function name (ignoring the namespace names that qualify it)
that appear in different namespace scopes refer to the same function."
Since a template function has one name but can be parameterized to
refer to different functions, this obviously can't work. It looks like
this shouldn't be a problem for template functions with internal
linkage but the standard doesn't make a special case to allow for that.
comp.std.c++ is a better place to discuss that though. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: JKop |
last post by:
Okay here we go, I feel it's about time people conversed about the bullshit
aspects of C++ (including the bullshit stuff brought forward from C). I'll
begin with a few of my own grievances:
1)...
|
by: tropostropos |
last post by:
On Solaris, using the Sun compiler, I get annoying warnings from the
following code. The problem is that I am passing a C++ member function
pointer to the C library function qsort. Is there a...
|
by: Daniele Benegiamo |
last post by:
Is the following program standard-compliant? I've compiled it with some
compilers and no errors or warnings are produced, but this is not a
demonstration.
The "incriminated" part is the...
|
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...
|
by: ccwork |
last post by:
Hi all,
I am reading "C: A Reference Manual" 4th ed and I get lost for the
"extern". It says that global object without specifying the
storage-class specifier will have "extern" as the default...
|
by: ryjfgjl |
last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
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...
|
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...
|
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,...
|
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...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
|
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,...
| |