Topic: Defect Report: allow C language linkage type for static memberfunction


Author: David R Tribble <david@tribble.com>
Date: 1999/09/27
Raw View
David R Tribble wrote:
>
> Darin Adler wrote:
> >
> > I wrote:
> > >> A thought on this point: I don't know of a single compiler that
> > >> correctly implements this rule yet that also distinguishes C and
> > >> C++ function pointers as required by the standard.
> >
> > David R Tribble <david@tribble.com> wrote:
> > > The IBM OS/390 (2.6+) C/C++ compiler complains about mismatching
> > > extern C and extern C++ function pointers.
> >
> > That's half of what I said above.
> >
> > Does it also implement the rule where you can't have a static member
> > function with extern "C" type?
>
> The following resulted in a syntax error:
>
>     class Foo
>     {
>     public:
>         extern "C" static int  bar();
>     };
>
>     int Foo::bar()
>     {
>         return 17;
>     }
>
>  4: Syntax error - expected "declarator" and found ""C"".

However, declaring an extern "C" static member function via a
typedef seems to work on at least a few compilers:

    extern "C"
    {
        typedef int     (CFunc)();       // extern C func
        typedef int     (*CFuncPtr)();   // extern C func ptr
    }

    class Foo
    {
    public:
        static CFunc    baz;     // extern C static member func
    };

    int Foo::baz()
    {
        return 23;
    }

    CFuncPtr    p = &Foo::baz;   // ptr to extern C func

But is this legal ISO C++?

-- David R. Tribble, david@tribble.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: David R Tribble <david@tribble.com>
Date: 1999/09/20
Raw View
Darin Adler wrote:
>
> I wrote:
> >> A thought on this point: I don't know of a single compiler that
> >> correctly implements this rule yet that also distinguishes C and C++
> >> function pointers as required by the standard.
>
> David R Tribble <david@tribble.com> wrote:
> > The IBM OS/390 (2.6+) C/C++ compiler complains about mismatching
> > extern C and extern C++ function pointers.
>
> That's half of what I said above.
>
> Does it also implement the rule where you can't have a static member
> function with extern "C" type?

The following resulted in a syntax error:

    class Foo
    {
    public:
        extern "C" static int  bar();
    };

    int Foo::bar()
    {
        return 17;
    }

 4: Syntax error - expected "declarator" and found ""C"".

-- David R. Tribble, david@tribble.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: David R Tribble <david@tribble.com>
Date: 1999/09/20
Raw View
Darin Adler wrote:
>
> Michael Ball <ball@eng.sun.com> wrote:
>
> > So don't put it into the header file!
> > Then you can be quite sure that nobody calls it.
>
> Then it can't be a friend. A static friend function must be declared
> before the friend declaration, so it has to be in the header file.
> That's what drove me toward a static member function in the first
> place.

So what is the proper syntax for declaring an extern C function
as a friend to a class?

    extern "C" int  foo();
    extern "C" int  bar();

    class Xyz
    {
        friend extern "C" int  foo();    // ?
        friend            int  bar();    // ?
        ...
    };

Is the 'extern "C"' correct or necessary?

-- David R. Tribble, david@tribble.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: comeau@panix.com (Greg Comeau)
Date: 1999/09/22
Raw View
In article <37E6BF43.B3EEFD19@tribble.com> David R Tribble <david@tribble.com> writes:
>
>Darin Adler wrote:
>>
>> I wrote:
>> >> A thought on this point: I don't know of a single compiler that
>> >> correctly implements this rule yet that also distinguishes C and C++
>> >> function pointers as required by the standard.
>>
>> David R Tribble <david@tribble.com> wrote:
>> > The IBM OS/390 (2.6+) C/C++ compiler complains about mismatching
>> > extern C and extern C++ function pointers.
>>
>> That's half of what I said above.
>>
>> Does it also implement the rule where you can't have a static member
>> function with extern "C" type?
>
>The following resulted in a syntax error:
>
>    class Foo
>    {
>    public:
>        extern "C" static int  bar();
>    };
>
>    int Foo::bar()
>    {
>        return 17;
>    }
>
> 4: Syntax error - expected "declarator" and found ""C"".

We (Comeau C++) kicks out both as well (including an option to accept
the former).  Darin, is there some sure bet problem example you are
thinking of?

- Greg
--
       Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418-3214
     Producers of Comeau C/C++ 4.2.38 -- NOTE 4.2.42 BETAS NOW AVAILABLE
    Email: comeau@comeaucomputing.com / Voice:718-945-0009 / Fax:718-441-2310
                *** WEB: http://www.comeaucomputing.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: "Darin Adler" <darin@bentspoon.com>
Date: 1999/09/14
Raw View
I wrote:
>> A thought on this point: I don't know of a single compiler that
>> correctly implements this rule yet that also distinguishes C and C++
>> function pointers as required by the standard.

David R Tribble <david@tribble.com> wrote:
> The IBM OS/390 (2.6+) C/C++ compiler complains about mismatching
> extern C and extern C++ function pointers.

That's half of what I said above.

Does it also implement the rule where you can't have a static member
function with extern "C" type?

    -- Darin
---
[ 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: Michael Ball <ball@eng.sun.com>
Date: 1999/09/15
Raw View
Darin Adler wrote:
>
> Michael Ball <ball@eng.sun.com> wrote:

> You're saying that a private function provides no additional hiding
> beyond that of a similarly named global function outside the class
> definition? I thought that a private function was better because I
> know that no one calls it.

No, it provides no additional hiding.  It does provide some access
protection, quite a different beast.  Since it's to be called via
a pointer, the protection issue seems minimal.

> Anything else in the header file -- inside or outside a namespace,
> internal or external linkage -- doesn't have that kind of guarantee,
> as I understand it.

So don't put it into the header file!

Then you can be quite sure that nobody calls it.

-Mike-


[ 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: Michael Ball <ball@eng.sun.com>
Date: 1999/09/13
Raw View
Darin Adler wrote:

> A thought on this point: I don't know of a single compiler that correctly
> implements this rule yet that also distinguishes C and C++ function pointers
> as required by the standard.

A statement about your self, not about compilers.  I do know of one,
so there! :-)  Sorry, but neither statement really affects the argument.

>                               So I don't think it's likely that most code
> will be updated by the five-year review. The only code that would be broken
> by this change would be code that:
>
>     1) tried to use C language linkage type for a static member function
> (with an extern "C" or the typedef technique)
>     2) due to the rule, instead got C++ language linkage type for the static
> member function
>     3) used the static member function in a way that will work with C++
> language linkage type only, such as passing a function pointer
>
> I don't think that will be particularly common.

No, but neither is the need likely to be particularly common.  The idea
of using a static member as a callback was always one of those "cute
ideas" that looked a lot more useful than it really is.  The only thing
you get from it is name hiding, and there are other ways around that.

>
> In fact, I wasn't aware of the typedef technique (using an extern "C"
> function type to declare a function with C language linkage type and C++
> language linkage name) until a few weeks ago when it was suggested to a
> large group of programmers on another list.

Changing the language for what is at best a minor inconvenience is very
hard to do at this point.  You must make the point that the value is
very large, because the cost of any change is inherently very large.

-Mike Ball-
Sun MicroSystems Inc


[ 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: "Darin Adler" <darin@bentspoon.com>
Date: 1999/09/13
Raw View
Michael Ball <ball@eng.sun.com> wrote:
> The idea of using a static member as a callback was always one of those
> "cute ideas" that looked a lot more useful than it really is.

I think that's a statement about yourself, not about the technique.

I'm surprised to hear that this "looks more useful than it really is";
I've been using it in most of my programs for the last ten years. I
never thought of it as "cute", merely the best approach to a situation
that arises in most of my Macintosh programs.

The technique works perfectly, except in the case where the callback
has C language function pointer type, something that didn't exist
until last year.

> The only thing you get from it is name hiding, and there are other ways
> around that.

I would be very interested in learning other ways around the hiding
problem. I've learned a good technique from Bill Wade's post, and I'll
be using that one and suggesting to other programmers, but it involves
what you've characterized as the "cute idea".

> Changing the language for what is at best a minor inconvenience is very
> hard to do at this point.  You must make the point that the value is
> very large, because the cost of any change is inherently very large.

Understood.

That's a good reason for the committee not to make the change, and
it's what I expect. I probably would have reported this after the
public comment draft, but the introduction of distinct C and C++
language linkage function types (an improvement, in my opinion)
happened late in the standardization process.

>> A thought on this point: I don't know of a single compiler that correctly
>> implements this rule yet that also distinguishes C and C++ function
>> pointers as required by the standard.

> I do know of one, so there!

Which one? (Just curious. You've already said that you don't think
this is pertinent.)

    -- Darin


[ 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 <david@tribble.com>
Date: 1999/09/14
Raw View
Darin Adler wrote:
>
> Me:
> > Here's a concrete example:
> >
> >     extern "C" typedef void c_linkage_func();
> >
> >     c_linkage_func non_member_func();
> >
> >     class C {
> >       static c_linkage_func static_member_func();
> >     };
>
> As Valentin pointed out, the correct example is:
>
>     extern "C" typedef void c_linkage_func();
>
>     c_linkage_func non_member_func;
>
>     class C {
>         static c_linkage_func static_member_func;
>     };
>
> I included some extra "()" by accident in the original.
>
> wmm@fastdial.net:
> > However, I'm very much afraid that at this point it's not
> > sufficiently broken to be fixable under defect report procedures,
> > and by the five-year review time it will have become a mostly moot
> > point, as most code will have been updated to reflect the
> > requirements in the Standard.
>
> A thought on this point: I don't know of a single compiler that
> correctly implements this rule yet that also distinguishes C and C++
> function pointers as required by the standard.

The IBM OS/390 (2.6+) C/C++ compiler complains about mismatching
extern C and extern C++ function pointers.

This caused us a little porting grief, but no too much since the only
real need we have for such things is to look up a function in a shared
library and then call it; by its nature, and in light of name
mangling, this really only works for extern C functions.

-- David R. Tribble, david@tribble.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: Michael Ball <ball@eng.sun.com>
Date: 1999/09/14
Raw View
Darin Adler wrote:
>
> Michael Ball <ball@eng.sun.com> wrote:
> > The idea of using a static member as a callback was always one of those
> > "cute ideas" that looked a lot more useful than it really is.
>
> I think that's a statement about yourself, not about the technique.

It's a statement about both.  It contains an opinion, and an (implicit)
statement that it's not terribly useful.  Both are, of course,
subjective.
However, I've paid my dues in the C++ world and I think I've earned the
right to hold opinions.

> The technique works perfectly, except in the case where the callback
> has C language function pointer type, something that didn't exist
> until last year.

It was never guaranteed by the language to work, or at least it could
be guaranteed only by draconian restrictions on calling sequence that
we weren't really willing to place on implementations.  Do you want to
insist that extern "Ada" functions have the same calling sequence as
extern "C" functions?  That was the restriction we would have to
impose if we hadn't made the change.

> > The only thing you get from it is name hiding, and there are other ways
> > around that.
>
> I would be very interested in learning other ways around the hiding
> problem. I've learned a good technique from Bill Wade's post, and I'll
> be using that one and suggesting to other programmers, but it involves
> what you've characterized as the "cute idea".

By far the easiest solution is simply to write a unique name.  Instead of
writing "foo::my_routine()" write "foo_my_routine()".  Both are merely
conventions.  If you don't like that, use a namespace or make the
function
static.

> >> A thought on this point: I don't know of a single compiler that correctly
> >> implements this rule yet that also distinguishes C and C++ function
> >> pointers as required by the standard.
>
> > I do know of one, so there!
>
> Which one? (Just curious. You've already said that you don't think
> this is pertinent.)

Sun C++ 5.0 and following releases.

-Mike Ball-


[ 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: "Darin Adler" <darin@bentspoon.com>
Date: 1999/09/14
Raw View
Michael Ball <ball@eng.sun.com> wrote:

> By far the easiest solution is simply to write a unique name.  Instead of
> writing "foo::my_routine()" write "foo_my_routine()".  Both are merely
> conventions.  If you don't like that, use a namespace or make the function
> static.

You're saying that a private function provides no additional hiding
beyond that of a similarly named global function outside the class
definition? I thought that a private function was better because I
know that no one calls it.

Anything else in the header file -- inside or outside a namespace,
internal or external linkage -- doesn't have that kind of guarantee,
as I understand it.

    -- Darin


[ 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              ]