Topic: function pointer types(was: atexit() behavior)
Author: AllanW@my-dejanews.com
Date: 1998/12/03 Raw View
In article <366656F7.6AD69015@physik.tu-muenchen.de>,
Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
>
>AllanW@my-dejanews.com wrote:
> >
> > In article <3663B9D8.283B0424@physik.tu-muenchen.de>,
> > Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
> > > Does that mean that I can do
> > >
> > > bool is_c_function(void(*)()) { return false; }
> > > extern "C"
> > > {
> > > bool is_c_function(void(*)()) { return true; }
> > > }
> >
> > This is equivalent to what the standard does, and (at least for
> > user-written code) it is illegal.
> >
> > > and use that to differentiate between C and C++ functions?
> >
> > I think you want is
> > bool is_c_function(extern "C" void(*)()) { return true; }
> > bool is_c_function(extern "C++" void(*)()) { return false; }
> > The difference here is that we're using two different parameter
> > types, rather than two different return types.
>
>But since my second function is declared in an extern "C" block,
>AFAIK the parameter should be a pointer to C function.
>BTW, I don't think you may use extern "C" inside the parameter list.
You're right. Your version should work, and mine is illegal.
Steve Clamage explained why in another post. Sorry if I misled you.
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/12/03 Raw View
In article <36655968.41C6@wizard.net>, James Kuyper <kuyper@wizard.net>
writes
>I think that it's the only such place. Why does the standard require
>this workaround?
I guess because rewriting the grammar for extern "<lang spec>" would
have been too time consuming at that stage.
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/12/02 Raw View
In article <741t78$a8v$1@nnrp1.dejanews.com>, AllanW@my-dejanews.com
writes
>I think you want is
> bool is_c_function(extern "C" void(*)()) { return true; }
> bool is_c_function(extern "C++" void(*)()) { return false; }
>The difference here is that we're using two different parameter
>types, rather than two different return types.
No. You are not allowed to place linkage specifiers in a function like
that.
A linkage specifier applies to all parts of a declaration.
That leaves a problem as to how you write a C++ linkage function that
takes a pointer to C linkage function (or any other combination you
like)
To do this you have to use a typedef:
extern "C" {
typedef void (*Cfunc_ptr)();
}
void func_cpp( Cfunc_ptr);
I believe this is one of those places where the grammar allows you to do
something with a typedef that cannot be written otherwise.
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/12/02 Raw View
AllanW@my-dejanews.com writes:
>> Does that mean that I can do
>>
>> bool is_c_function(void(*)()) { return false; }
>> extern "C"
>> {
>> bool is_c_function(void(*)()) { return true; }
>> }
>This is equivalent to what the standard does, and (at least for
>user-written code) it is illegal.
No, it is legal. The parameters have the linkage of the
function, and so are different types.
>I think you want is
> bool is_c_function(extern "C" void(*)()) { return true; }
> bool is_c_function(extern "C++" void(*)()) { return false; }
>The difference here is that we're using two different parameter
>types, rather than two different return types.
But language linkage can appear only at namespace scope. This
code is both illegal and unnecessary.
--
Steve Clamage, stephen.clamage@sun.com
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/12/02 Raw View
Francis Glassborow wrote:
...
> A linkage specifier applies to all parts of a declaration.
> That leaves a problem as to how you write a C++ linkage function that
> takes a pointer to C linkage function (or any other combination you
> like)
> To do this you have to use a typedef:
> extern "C" {
> typedef void (*Cfunc_ptr)();
> }
> void func_cpp( Cfunc_ptr);
> I believe this is one of those places where the grammar allows you to do
> something with a typedef that cannot be written otherwise.
I think that it's the only such place. Why does the standard require
this workaround?
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: AllanW@my-dejanews.com
Date: 1998/12/02 Raw View
In article <74220p$3hl$1@engnews2.Eng.Sun.COM>,
stephen.clamage@sun.com (Steve Clamage) wrote:
>
> AllanW@my-dejanews.com writes:
>
> >> Does that mean that I can do
> >>
> >> bool is_c_function(void(*)()) { return false; }
> >> extern "C"
> >> {
> >> bool is_c_function(void(*)()) { return true; }
> >> }
>
> >This is equivalent to what the standard does, and (at least for
> >user-written code) it is illegal.
>
> No, it is legal. The parameters have the linkage of the
> function, and so are different types.
>
> >I think you want is
> > bool is_c_function(extern "C" void(*)()) { return true; }
> > bool is_c_function(extern "C++" void(*)()) { return false; }
> >The difference here is that we're using two different parameter
> >types, rather than two different return types.
>
> But language linkage can appear only at namespace scope. This
> code is both illegal and unnecessary.
Yes, I see that now; another post of yours pointed me to the correct
section of the standard.
But how would you declare two functions, both with C++ linkage,
both accepting one parameter, where the first function's parameter
is pointer-to-C-function and the second function's parameter is
pointer-to-C++-function?
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/12/03 Raw View
AllanW@my-dejanews.com wrote:
...
> But how would you declare two functions, both with C++ linkage,
> both accepting one parameter, where the first function's parameter
> is pointer-to-C-function and the second function's parameter is
> pointer-to-C++-function?
extern "C" typedef void c_func();
extern "C++" func1(c_func *f);
extern "C++" func2(void (*f)());
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/12/03 Raw View
AllanW@my-dejanews.com wrote:
>
> In article <3663B9D8.283B0424@physik.tu-muenchen.de>,
> Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
> >
> > Francis Glassborow wrote:
> >
> > [...]
> >
> > > I think they have different signatures because the parameters are:
> > >
> > > pointer to extern "C" function
> > > and
> > > pointer to extern "C++" function
> > >
> > > and these types are differentiable.
>
> Makes sense, but not so. The parameters are identical.
>
> > Does that mean that I can do
> >
> > bool is_c_function(void(*)()) { return false; }
> > extern "C"
> > {
> > bool is_c_function(void(*)()) { return true; }
> > }
>
> This is equivalent to what the standard does, and (at least for
> user-written code) it is illegal.
>
> > and use that to differentiate between C and C++ functions?
>
> I think you want is
> bool is_c_function(extern "C" void(*)()) { return true; }
> bool is_c_function(extern "C++" void(*)()) { return false; }
> The difference here is that we're using two different parameter
> types, rather than two different return types.
But since my second function is declared in an extern "C" block,
AFAIK the parameter should be a pointer to C function.
BTW, I don't think you may use extern "C" inside the parameter list.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/12/01 Raw View
Christopher Eltschka wrote:
> Francis Glassborow wrote:
> [...]
> > I think they have different signatures because the parameters are:
> >
> > pointer to extern "C" function
> > and
> > pointer to extern "C++" function
> >
> > and these types are differentiable.
> Does that mean that I can do
> bool is_c_function(void(*)()) { return false; }
> extern "C"
> {
> bool is_c_function(void(*)()) { return true; }
> }
> and use that to differentiate between C and C++ functions?
No. The atexit() functions take an argument which can be either "C" or
"C++", and you can overload on argument types. Both of your functions
have the same argument type. How would the compiler know which one to
call?
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/12/01 Raw View
In article <3663B9D8.283B0424@physik.tu-muenchen.de>, Christopher
Eltschka <celtschk@physik.tu-muenchen.de> writes
>
>Francis Glassborow wrote:
>
>[...]
>
>> I think they have different signatures because the parameters are:
>>
>> pointer to extern "C" function
>> and
>> pointer to extern "C++" function
>>
>> and these types are differentiable.
>
>Does that mean that I can do
>
>bool is_c_function(void(*)()) { return false; }
>extern "C"
>{
> bool is_c_function(void(*)()) { return true; }
>}
>
>and use that to differentiate between C and C++ functions?
Fundamentally (I would have to check the fine detail), yes, but only
between functions taking no variables and returning void. I leave you
to turn that into a template:)
>
>BTW, is there (in any direction) an automatic conversion between
>C and C++ function pointers?
Only if such a conversion can be provided. IOW if the calling sequences
are different then you canot make the conversion. It was because
development environments exist where the calling conventions are
different (I believe) IBM's is one such) that the decision to allow the
distinction on linkage specification was made.
>That is, is any of the following initialisations allowed?
>
>extern "C" { typedef void (*c_ptr)(); }
>typedef void (*cpp_ptr)();
>
>extern "C" void f();
>void g();
>void h() throw();
>
>cpp_ptr p1 = &f; // allowed?
only if conversion is available (implementation dependant)
>c_ptr p2 = &g; // allowed?
likewise
>c_ptr p3 = &h; // allowed?
I don't know, but I think that would be implementation dependant as
well.
This is an odd use of implementation dependant in so far as I think code
may or may not compile depending on the implementation. If I am wrong
and it must compile, the result would be undefined behaviour if C and
C++ functions are not call compatible.
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/12/01 Raw View
Francis Glassborow <francis@robinton.demon.co.uk> writes:
>>BTW, is there (in any direction) an automatic conversion between
>>C and C++ function pointers?
>Only if such a conversion can be provided.
Only if the programmer writes a conversion function or uses
a reinterpret_cast.
>>That is, is any of the following initialisations allowed?
[ mixing extern "C" and extern "C++" pointers to functions ]
>I don't know, but I think that would be implementation dependant as
>well.
It is disallowed by the standard. The pointers have different
types and are not related by inheritance. There is no
implicit conversion.
See 7.5 in the standard.
--
Steve Clamage, stephen.clamage@sun.com
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/12/01 Raw View
In article <741a3r$otq$1@engnews2.Eng.Sun.COM>, Steve Clamage
<stephen.clamage@sun.com> writes
>It is disallowed by the standard. The pointers have different
>types and are not related by inheritance. There is no
>implicit conversion.
But in reality I would expect most implementors in anything but strict
mode will allow the conversion.
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: AllanW@my-dejanews.com
Date: 1998/12/01 Raw View
In article <3663B9D8.283B0424@physik.tu-muenchen.de>,
Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
>
> Francis Glassborow wrote:
>
> [...]
>
> > I think they have different signatures because the parameters are:
> >
> > pointer to extern "C" function
> > and
> > pointer to extern "C++" function
> >
> > and these types are differentiable.
Makes sense, but not so. The parameters are identical.
> Does that mean that I can do
>
> bool is_c_function(void(*)()) { return false; }
> extern "C"
> {
> bool is_c_function(void(*)()) { return true; }
> }
This is equivalent to what the standard does, and (at least for
user-written code) it is illegal.
> and use that to differentiate between C and C++ functions?
I think you want is
bool is_c_function(extern "C" void(*)()) { return true; }
bool is_c_function(extern "C++" void(*)()) { return false; }
The difference here is that we're using two different parameter
types, rather than two different return types.
> BTW, is there (in any direction) an automatic conversion between
> C and C++ function pointers?
I didn't look it up, but I'm almost sure that the answer is NO.
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/12/01 Raw View
Francis Glassborow wrote:
[...]
> I think they have different signatures because the parameters are:
>
> pointer to extern "C" function
> and
> pointer to extern "C++" function
>
> and these types are differentiable.
Does that mean that I can do
bool is_c_function(void(*)()) { return false; }
extern "C"
{
bool is_c_function(void(*)()) { return true; }
}
and use that to differentiate between C and C++ functions?
BTW, is there (in any direction) an automatic conversion between
C and C++ function pointers?
That is, is any of the following initialisations allowed?
extern "C" { typedef void (*c_ptr)(); }
typedef void (*cpp_ptr)();
extern "C" void f();
void g();
void h() throw();
cpp_ptr p1 = &f; // allowed?
c_ptr p2 = &g; // allowed?
c_ptr p3 = &h; // allowed?
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]