473,385 Members | 1,958 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,385 software developers and data experts.

Query: How to declare a template class member function 'extern "C"' ?

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 solution?
Declaring the function extern "C" fails, because linkage declarations
must be made at file scope.

#include <stdlib.h> //for qsort

template <class T>
class Sorter
{
public:

//CompareVector is passed to qsort, which requires a C function
pointer parameter.
//extern "C" { static int CompareVector (t void *otPt1, const void
*otPt2;} //Wont compile!
static int CompareVector (const void *otPt1, const void *otPt2);
//Gets warning!
void InternalSort ();

T **vptPoints;
int viNumPoints;

};
template <class T>
void Sorter<T>::InternalSort ()
{
qsort( vptPoints, viNumPoints, sizeof (T*), CompareVector
); //last param should be extern "C"!
}

template <class T>
int Sorter<T>::CompareVector (const void *otPt1, const void *otPt2)
{
return 0; //We don't bother executing it: toy code to fix
compilation warning.
}

int main()
{

Sorter<int> s;
s.InternalSort();

}

Aug 3 '05 #1
9 8223
Will you please post the warnings/errors as reported by the compiler?

-Wg-

Aug 3 '05 #2
tr**********@hotmail.com wrote:
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 solution?
Declaring the function extern "C" fails, because linkage declarations
must be made at file scope.

#include <stdlib.h> //for qsort

template <class T>
class Sorter
{
public:

//CompareVector is passed to qsort, which requires a C function
pointer parameter.
//extern "C" { static int CompareVector (t void *otPt1, const void
*otPt2;} //Wont compile!
static int CompareVector (const void *otPt1, const void *otPt2);
//Gets warning!
void InternalSort ();

T **vptPoints;
int viNumPoints;

};
template <class T>
void Sorter<T>::InternalSort ()
{
qsort( vptPoints, viNumPoints, sizeof (T*), CompareVector
); //last param should be extern "C"!
}

template <class T>
int Sorter<T>::CompareVector (const void *otPt1, const void *otPt2)
{
return 0; //We don't bother executing it: toy code to fix
compilation warning.
}

int main()
{

Sorter<int> s;
s.InternalSort();

}


As long as the program tries to use a member function pointer as a
callback routine, it will never be able to run correctly.

Member function pointers cannot be used as callback routines because an
instance of the class is always needed in order to call the member
function through a pointer. Qsort has no instance of a class Sorter<T>
handy, so it has no way of calling CompareVector to make the
comparison.

Even if qsort had an instance of a Sorter, it would still not be able
to invoke the callback correctly. There is a mismatch in the argument
lists of the two routines: CompareVector accepts three parameters,
while the qsort callback takes two only. Now it may appear that I
miscounted: CompareVector's declaration certainly looks like only two
arguments are accepted. But when counting parameters, we must also
count the hidden, "this" parameter passed to member functions. Qsort
knows nothing about this parameter, so not only would the "this"
parameter be missing from qsort's argument list passed to the callback,
the two parameters that it did include would be shifted over one
register from the location where CompareVector expects to find them.

Given that the classes involved in the sort operation are templates, I
would suggest looking at std::sort instead of qsort as an easier, more
C++ solution to the problem.

Greg

Aug 3 '05 #3
The code as it stands generates the following warning:

"test.cpp", line 22: Warning (Anachronism): Formal argument 4 of type
extern "C" int(*)(const void*,const void*) in call to std::qsort(void*,
unsigned, unsigned, extern "C" int(*)(const void*,const void*)) is
being passed int(*)(const void*,const void*).
"test.cpp", line 35: Where: While instantiating
"Sorter<int>::InternalSort()".
"test.cpp", line 35: Where: Instantiated from non-template code.
1 Warning(s) detected.

If I comment out the declaration labelled "Gets Warning!" and I
un-comment-out the declaration labelled "Wont compile!", then I get the
following errors:

"test.cpp", line 21: Error: InternalSort() is not a member of
Sorter<T>.
"test.cpp", line 27: Error: CompareVector(const void*, const void*) is
not a member of Sorter<T>.
"test.cpp", line 9: Error: Linkage specifications are allowed only at
file level.
"test.cpp", line 34: Where: While specializing "Sorter<int>".
"test.cpp", line 34: Where: Specialized in non-template code.
"test.cpp", line 9: Error: storage class extern not allowed for a
member.
"test.cpp", line 34: Where: While specializing "Sorter<int>".
"test.cpp", line 34: Where: Specialized in non-template code.
"test.cpp", line 9: Error: A declaration does not specify a tag or an
identifier.
"test.cpp", line 34: Where: While specializing "Sorter<int>".
"test.cpp", line 34: Where: Specialized in non-template code.
"test.cpp", line 9: Error: Use ";" to terminate declarations.
"test.cpp", line 34: Where: While specializing "Sorter<int>".
"test.cpp", line 34: Where: Specialized in non-template code.
"test.cpp", line 9: Error: "}" expected instead of "{".
"test.cpp", line 34: Where: While specializing "Sorter<int>".
"test.cpp", line 34: Where: Specialized in non-template code.
"test.cpp", line 35: Error: InternalSort is not a member of
Sorter<int>.
8 Error(s) detected.

Aug 3 '05 #4

<tr**********@hotmail.com> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com...
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 solution?
Declaring the function extern "C" fails, because linkage declarations
must be made at file scope.

#include <stdlib.h> //for qsort

template <class T>
class Sorter
{
public:

//CompareVector is passed to qsort, which requires a C function
pointer parameter.
//extern "C" { static int CompareVector (t void *otPt1, const void
What is "t void" supposed to be?

*otPt2;} //Wont compile!
static int CompareVector (const void *otPt1, const void *otPt2);
//Gets warning!
void InternalSort ();

T **vptPoints;
int viNumPoints;

};
template <class T>
void Sorter<T>::InternalSort ()
{
qsort( vptPoints, viNumPoints, sizeof (T*), CompareVector
); //last param should be extern "C"!
}

template <class T>
int Sorter<T>::CompareVector (const void *otPt1, const void *otPt2)
{
return 0; //We don't bother executing it: toy code to fix
compilation warning.
}

int main()
{

Sorter<int> s;
s.InternalSort();

}

Aug 3 '05 #5
As long as the program tries to use a member function pointer as a
callback routine, it will never be able to run correctly.


The OP declared his callback function static, which is fine for callback.
The problem is the compiler error with extern "C", which is a thing for
linkers and I don't think it is needed.

Ben
Aug 3 '05 #6
I don't think the extern "C" is needed. I am not sure but I guess it merely
tells the compiler to emit C function symbol (as opposed to the mangled C++
symbol) for linking.

Otherwise consider sharing a non-template base and make the actual
comparison virtual, then retrofit a global (extern "C") function to wrap the
virtual call.

Ben
Aug 3 '05 #7
* benben:
As long as the program tries to use a member function pointer as a
callback routine, it will never be able to run correctly.
The OP declared his callback function static, which is fine for callback.


No, it isn't.

Some compilers allow it, in the same way they (or should I say, MSVC) allow
'int main'.

That doesn't make it valid C++.

The problem is the compiler error with extern "C", which is a thing for
linkers and I don't think it is needed.


It is needed.

The solution in this case and most other cases is to do things at the C++
level instead of the C level, i.e., here, to use std::sort.

--
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?
Aug 3 '05 #8
A reply to Greg's comment that <<we must also count the hidden, "this"
parameter passed to member functions.>> :

But static member functions (like CompareVector) do not have a hidden
"this" parameter pointing to an instance, and no instance is required
to invoke a static member function. So that should not be a problem
for qsort.

I suspect that C++ simply does not permit member functions to have "C"
linkage. So what is the simplest workaround?

Aug 3 '05 #9
tr**********@hotmail.com wrote:
The code as it stands generates the following warning:

"test.cpp", line 22: Warning (Anachronism): Formal argument 4 of type
extern "C" int(*)(const void*,const void*) in call to std::qsort(void*,
unsigned, unsigned, extern "C" int(*)(const void*,const void*)) is
being passed int(*)(const void*,const void*).
"test.cpp", line 35: Where: While instantiating
"Sorter<int>::InternalSort()".
"test.cpp", line 35: Where: Instantiated from non-template code.
1 Warning(s) detected.

If I comment out the declaration labelled "Gets Warning!" and I
un-comment-out the declaration labelled "Wont compile!", then I get the
following errors:

"test.cpp", line 21: Error: InternalSort() is not a member of
Sorter<T>.
"test.cpp", line 27: Error: CompareVector(const void*, const void*) is
not a member of Sorter<T>.
"test.cpp", line 9: Error: Linkage specifications are allowed only at
file level.
"test.cpp", line 34: Where: While specializing "Sorter<int>".
"test.cpp", line 34: Where: Specialized in non-template code.
"test.cpp", line 9: Error: storage class extern not allowed for a
member.
"test.cpp", line 34: Where: While specializing "Sorter<int>".
"test.cpp", line 34: Where: Specialized in non-template code.
"test.cpp", line 9: Error: A declaration does not specify a tag or an
identifier.
"test.cpp", line 34: Where: While specializing "Sorter<int>".
"test.cpp", line 34: Where: Specialized in non-template code.
"test.cpp", line 9: Error: Use ";" to terminate declarations.
"test.cpp", line 34: Where: While specializing "Sorter<int>".
"test.cpp", line 34: Where: Specialized in non-template code.
"test.cpp", line 9: Error: "}" expected instead of "{".
"test.cpp", line 34: Where: While specializing "Sorter<int>".
"test.cpp", line 34: Where: Specialized in non-template code.
"test.cpp", line 35: Error: InternalSort is not a member of
Sorter<int>.
8 Error(s) detected.


This file:
=========================

#include <stdlib.h>

class A
{
public:
int i[100];
static int cmp(const void *v1, const void *v2)
{ return(* (int *) v1 - * (int *) v2); }
};

void foo(A &a) { qsort(a.i, 100, sizeof(a.i[0]), A::cmp); }

==========================
compiles without warnings using GCC (on Solaris). Whether
or not the class is templeted should be irrelevant.

I guess the point of the warnings your compiler is giving
is that the code would not be portable to an environment
where the C and C++ compilers use different calling conventions.
But I'm not sure that the Standard allows for linkage specifiers
to trigger the use of different calling conventions in the
object code.

Aug 3 '05 #10

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

Similar topics

2
by: Shea Martin | last post by:
I am trying to use a system call which takes a function ptr. My compiler won't compile the code if I give the system_call a ptr to a class member function, A::func(). To combat this, I created an...
1
by: terrencel | last post by:
I was told to look at some old C code that was ported to C++. One of the file is like: ========================================= CPPClass* someCPPVar = NULL; extern "C" {
3
by: Randy Yates | last post by:
Hi, Is there a way to write a class member function that does not require an instantiation of the object to be invoked? For example, class MYCLASS { bool CheckIfMYCLASS(string &teststring);...
22
by: Ian | last post by:
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...
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) {
4
by: Dan Stromberg | last post by:
Hi folks. I'm working on building some software, some of which is written in C++, for a researcher here at the University. I have an extensive background in C and python, but I haven't done...
5
by: Cmtk Software | last post by:
The following code: public __gc class MyClass { public: void MyFunc (int __gc* number); }; Generates the following metadata for C# when compiled in VC 2005 with the /clr:oldsyntax switch...
2
by: mahesh | last post by:
Can anyone direct me to the place where i find the solution for the error message "cannot call member function 'X' without object"??? thanks in advance
14
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...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
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...
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
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
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
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...

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.