Topic: Templates and Calling Conventions


Author: James Kuyper <kuyper@wizard.net>
Date: 1999/03/24
Raw View
AllanW {formerly AllanW@my-dejanews.com} wrote:
....
> In article <36F39F38.9C1EB0C8@abraxis.com>,
>   eddielee@abraxis.com wrote:
> > Calling conventions, like __stdcall, are purely an addition of compiler
> > vendors and have no place in the C++ standard, much less template
> > mechanisms.
>
> Well, yes, to a point this is true. But I think you're being too
> literal. The C++ standard defines a standard hook for calling
> conventions, and though the specific example that Mr. Barry cited
> doesn't use that hook, it certainly could.

Not within standard C++, if the hook's going to be applied to member
functions; you can't apply non-C++ language linkages to member
functions.

> So consider this alternative question in place of Mr. Barry's:
>
>     Templates such as mem_fun do not work with functions that use
>     different calling conventions. For example, with one popular
>     compiler's extensible system, methods are required to use a
>     keyword semantically equivalent to
>         extern "pascal"
>     where pascal is an implementation-defined calling convention.

I'm confused by that description. ALL methods are required to use that
keyword? Why have a keyword? Just make the keyword implicit in the
definition of a method. I know nothing about COM, but if all objects
that work with it are required to use this calling method for all
members, then define that fact to be a characteristic of the class,
rather than of it's members. Then mem_fun() will work fine, because it
is templated by the class.

>     In this system, an attempt to instantiate mem_fun with such a
>     method gives an error that indicates that mem_fun's first
>     argument should not have used a foreign calling convention.

>     I believe that the essence of Mr. Barry's question is: "should
>     mem_fun's first parameter have been a template type, so that it
>     could work for functions with any calling convention? Or is
>     there some reason to leave this implementation-defined?"

Within standard C++, member functions must have "C++" language linkage,
so there's no need to allow for other possibilities. If an implementor
choses to provide other possibilities, then figuring out how to cope
with the resulting mess is their responsibility, not the Standard's.


[ 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: David R Tribble <dtribble@technologist.com>
Date: 1999/03/24
Raw View
James Kuyper wrote:
> AllanW {formerly AllanW@my-dejanews.com} wrote:
> ....
>> In article <36F39F38.9C1EB0C8@abraxis.com>,
>>   eddielee@abraxis.com wrote:
>>> Calling conventions, like __stdcall, are purely an addition of
>>> compiler vendors and have no place in the C++ standard, much less
>>> template mechanisms.
>>
>> Well, yes, to a point this is true. But I think you're being too
>> literal. The C++ standard defines a standard hook for calling
>> conventions, and though the specific example that Mr. Barry cited
>> doesn't use that hook, it certainly could.
>
> Not within standard C++, if the hook's going to be applied to member
> functions; you can't apply non-C++ language linkages to member
> functions.
>
>> So consider this alternative question in place of Mr. Barry's:
>>     Templates such as mem_fun do not work with functions that use
>>     different calling conventions. For example, with one popular
>>     compiler's extensible system, methods are required to use a
>>     keyword semantically equivalent to
>>         extern "pascal"
>>     where pascal is an implementation-defined calling convention.
>
> I'm confused by that description. ALL methods are required to use that
> keyword? Why have a keyword? Just make the keyword implicit in the
> definition of a method. I know nothing about COM, but if all objects
> that work with it are required to use this calling method for all
> members, then define that fact to be a characteristic of the class,
> rather than of it's members. Then mem_fun() will work fine, because it
> is templated by the class.
>
>>     In this system, an attempt to instantiate mem_fun with such a
>>     method gives an error that indicates that mem_fun's first
>>     argument should not have used a foreign calling convention.
>>
>>     I believe that the essence of Mr. Barry's question is: "should
>>     mem_fun's first parameter have been a template type, so that it
>>     could work for functions with any calling convention? Or is
>>     there some reason to leave this implementation-defined?"
>
> Within standard C++, member functions must have "C++" language
> linkage, so there's no need to allow for other possibilities. If an
> implementor choses to provide other possibilities, then figuring out
> how to cope with the resulting mess is their responsibility, not the
> Standard's.

FWIW, I compiled the following code under MS-Visual C++ 5.0 (build
11.00.7022) and it worked just fine.

    //================================================================
    //   Test the '__stdcall' gibberish of Win32 with C++ member
    //   functions.
    //---------------------------------------------------------------

    #include <stdio.h>

    class Foo
    {
    public:
        static void __stdcall   baz();
        void __stdcall          bar();
    };

    /*static*/
    void __stdcall Foo::baz()
    {
        printf("Foo::baz()\n");
    }

    void __stdcall Foo::bar()
    {
        printf("Foo::bar()\n");
    }

    int main()
    {
        Foo     f;

        f.bar();
        f.baz();
        return (0);
    }

So it appears that MS-VC++ allows '__stdcall' as a modifier on
member function declarations, and that it acts a fictional
'extern "pascal"' would act.

-- David R. Tribble, dtribble@technologist.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: Stephen.Clamage@sun.com (Steve Clamage)
Date: 1999/03/21
Raw View
"Jim Barry" <jim.barry@bigfoot.com> writes:

>Templates such as mem_fun do not work with functions that use
>different calling conventions. For example, in COM, methods are
>required to use the pascal calling convention (__stdcall). Using MSVC,
>an attempt to instantiate mem_fun with such a method gives an error
>such as:

>error C2664: 'class std::mem_fun_t<long,struct Interface> __cdecl
>std::mem_fun(long (Interface::*)(void))' : cannot convert parameter 1
>from 'long (__stdcall Interface::*)(void)' to 'long
>(Interface::*)(void)'

>My question is: should/could the standard require the template
>mechanism to take calling convention into account, or is it purely a
>Quality of Implementation issue as the standard is not concerned with
>calling conventions?

Calling conventions are the reason linkage specifiers were
made part of C++. That is precisely their purpose.

If the compiler supports a particular calling convention different
from both extern "C" and extern "C++", it should define a new
linkage specifier for you to use. Linkage specification is part of
the type of a pointer-to-function.

But linkage specifications cannot be applied to class member
functions; they must have C++ linkage. The reason is that class
member functions might have special calling requirements,
and the standard cannot demand implementations allow them
to work with an arbitrary calling sequence (linkage).

An implementation might choose to allow linkage specifications
on class member functions as an extension, of course. Maybe
something like this:
    class T {
        extern "COM" int f(int); // special case
 extern "C" int g(int); // most likely disallowed
    };

But the C++ standard library expects C++ linkage functions,
not COM linkage functions. It might be possible to support
COM by providing specializations of the library classes and
functions that work with COM-linkage functions, but it might
be necessary to provide a separate COM version of the library
and headers.

--
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: Edward Diener <eddielee@abraxis.com>
Date: 1999/03/21
Raw View
Calling conventions, like __stdcall, are purely an addition of compiler
vendors and have no place in the C++ standard, much less template mechanisms.

Jim Barry wrote:

> Templates such as mem_fun do not work with functions that use
> different calling conventions. For example, in COM, methods are
> required to use the pascal calling convention (__stdcall). Using MSVC,
> an attempt to instantiate mem_fun with such a method gives an error
> such as:
>
> error C2664: 'class std::mem_fun_t<long,struct Interface> __cdecl
> std::mem_fun(long (Interface::*)(void))' : cannot convert parameter 1
> from 'long (__stdcall Interface::*)(void)' to 'long
> (Interface::*)(void)'
>
> My question is: should/could the standard require the template
> mechanism to take calling convention into account, or is it purely a
> Quality of Implementation issue as the standard is not concerned with
> calling conventions?
---
[ 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 {formerly AllanW@my-dejanews.com}" <allan_w@my-dejanews.com>
Date: 1999/03/23
Raw View

> Jim Barry wrote:
>
> > Templates such as mem_fun do not work with functions that use
> > different calling conventions. For example, in COM, methods are
> > required to use the pascal calling convention (__stdcall). Using MSVC,
> > an attempt to instantiate mem_fun with such a method gives an error
> > such as:
> >
> > error C2664: 'class std::mem_fun_t<long,struct Interface> __cdecl
> > std::mem_fun(long (Interface::*)(void))' : cannot convert parameter 1
> > from 'long (__stdcall Interface::*)(void)' to 'long
> > (Interface::*)(void)'
> >
> > My question is: should/could the standard require the template
> > mechanism to take calling convention into account, or is it purely a
> > Quality of Implementation issue as the standard is not concerned with
> > calling conventions?

In article <36F39F38.9C1EB0C8@abraxis.com>,
  eddielee@abraxis.com wrote:
> Calling conventions, like __stdcall, are purely an addition of compiler
> vendors and have no place in the C++ standard, much less template
> mechanisms.

Well, yes, to a point this is true. But I think you're being too
literal. The C++ standard defines a standard hook for calling
conventions, and though the specific example that Mr. Barry cited
doesn't use that hook, it certainly could.

So consider this alternative question in place of Mr. Barry's:

    Templates such as mem_fun do not work with functions that use
    different calling conventions. For example, with one popular
    compiler's extensible system, methods are required to use a
    keyword semantically equivalent to
        extern "pascal"
    where pascal is an implementation-defined calling convention.
    In this system, an attempt to instantiate mem_fun with such a
    method gives an error that indicates that mem_fun's first
    argument should not have used a foreign calling convention.

    I believe that the essence of Mr. Barry's question is: "should
    mem_fun's first parameter have been a template type, so that it
    could work for functions with any calling convention? Or is
    there some reason to leave this implementation-defined?"

----
Allan_W@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: "Jim Barry" <jim.barry@bigfoot.com>
Date: 1999/03/20
Raw View
Templates such as mem_fun do not work with functions that use
different calling conventions. For example, in COM, methods are
required to use the pascal calling convention (__stdcall). Using MSVC,
an attempt to instantiate mem_fun with such a method gives an error
such as:

error C2664: 'class std::mem_fun_t<long,struct Interface> __cdecl
std::mem_fun(long (Interface::*)(void))' : cannot convert parameter 1
from 'long (__stdcall Interface::*)(void)' to 'long
(Interface::*)(void)'

My question is: should/could the standard require the template
mechanism to take calling convention into account, or is it purely a
Quality of Implementation issue as the standard is not concerned with
calling conventions?

--
Jim Barry, Thermoteknix Systems Ltd., Cambridge, UK.
http://www.thermoteknix.co.uk - Queen's Award for Export 1998
http://www.geocities.com/SiliconValley/2060
---
[ 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              ]