Thread overview | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
July 22, 2003 Bug: Co-variance reported with different calling convention | ||||
---|---|---|---|---|
| ||||
class X { extern(Windows): void x() { printf("X::x()\n"); } } class Y : X { void x() { printf("Y::x()\n"); } } "combase_test.d(51): function x overrides but is not covariant with x" I strongly suspect that this is not just an omission, but something that has been discussed and is a deliberate behaviour. If that is so, can someone enlighten me as to the rationale? :) Matthew |
July 22, 2003 Re: Co-variance reported with different calling convention | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matthew Wilson | > I strongly suspect that this is not just an omission, but something that has > been discussed and is a deliberate behaviour. If that is so, can someone enlighten me as to the rationale? Of course, even if it deliberately cannot intuit the calling convention, the error message is still wrong. (Unless one counts co-variance to include calling convention, of course ...) |
July 22, 2003 Re: Bug: Co-variance reported with different calling convention | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matthew Wilson | I assume the problem is the same as if you had overloaded the function with one with a different return value. The two functions have the same calling parameters, but they have different signatures. A calling function that is expecting extern(Windows) but gets the non-extern version will break, and vice-versa.
Matthew Wilson wrote:
> class X
> {
> extern(Windows):
> void x()
> {
> printf("X::x()\n");
> }
> }
>
> class Y
> : X
> {
> void x()
> {
> printf("Y::x()\n");
> }
> }
>
>
> "combase_test.d(51): function x overrides but is not covariant with x"
>
>
> I strongly suspect that this is not just an omission, but something that has
> been discussed and is a deliberate behaviour. If that is so, can someone
> enlighten me as to the rationale?
>
> :)
>
> Matthew
>
>
|
July 24, 2003 Re: Bug: Co-variance reported with different calling convention | ||||
---|---|---|---|---|
| ||||
Posted in reply to Russ Lewis | I get that. My point was that it either doesn't make sense, or is arbitrarily strict, depending on one's viewpoint. Further, this will run into problems with templates, when one wants to use bolt-ins (which is precisely what I was laying the groundwork for with the work that precipitated the error), and will thus dramatically complicate the lives of template library writers. If anyone can see a significant +ve to the current behaviour, please tell, and I'll know to abandon this quest, otherwise I'll have to keep banging on about it until something gives. (That something is, of course, you Walter! <@>) "Russ Lewis" <spamhole-2001-07-16@deming-os.org> wrote in message news:bfje0h$1jlo$1@digitaldaemon.com... > I assume the problem is the same as if you had overloaded the function with one with a different return value. The two functions have the same calling parameters, but they have different signatures. A calling function that is expecting extern(Windows) but gets the non-extern version will break, and vice-versa. > > Matthew Wilson wrote: > > class X > > { > > extern(Windows): > > void x() > > { > > printf("X::x()\n"); > > } > > } > > > > class Y > > : X > > { > > void x() > > { > > printf("Y::x()\n"); > > } > > } > > > > > > "combase_test.d(51): function x overrides but is not covariant with x" > > > > > > I strongly suspect that this is not just an omission, but something that has > > been discussed and is a deliberate behaviour. If that is so, can someone enlighten me as to the rationale? > > > > :) > > > > Matthew > > > > > |
July 28, 2003 Re: Bug: Co-variance reported with different calling convention | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matthew Wilson | Hi Matthew, you wrote: >> > class X >> > { >> > extern(Windows): >> > void x() >> > { >> > printf("X::x()\n"); >> > } >> > } >> > >> > class Y >> > : X >> > { >> > void x() >> > { >> > printf("Y::x()\n"); >> > } >> > } As you know, any occurence of class X must be substitutable for class Y. This must be true from a designer's perspective *and* from the compiler's view. But due to the different calling convention of X.x() and Y.x(), calling Y.x() instead of X.x() is not possible in a straight way. Yes, the compiler could generate code to make it work (behind your back), but the programmer could easily make that, too. > Further, this will run into problems with templates, when one wants to use bolt-ins (which is precisely what I was laying the groundwork for with the work that precipitated the error), and will thus dramatically complicate the lives of template library writers. Have you link at hand for an article about bolt-ins (from you)? I enjoyed that one about shims. Farmer. |
July 29, 2003 Re: Bug: Co-variance reported with different calling convention | ||||
---|---|---|---|---|
| ||||
Posted in reply to Farmer | > Have you link at hand for an article about bolt-ins (from you)? Alas no. You may have to wait for the book. ;) (I'm doing those chapters at the moment.) > I enjoyed that one about shims. Please to hear it. |
July 29, 2003 Re: Bug: Co-variance reported with different calling convention | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matthew Wilson | > Please to hear it.
Pleased to hear it, I meant
|
August 30, 2003 Re: Co-variance reported with different calling convention | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matthew Wilson | The problem is that the calling conventions for X.x and Y.x are different, yet being virtual, they must have the same calling convention. "Matthew Wilson" <matthew@stlsoft.org> wrote in message news:bfj6h0$1cbf$1@digitaldaemon.com... > > class X > { > extern(Windows): > void x() > { > printf("X::x()\n"); > } > } > > class Y > : X > { > void x() > { > printf("Y::x()\n"); > } > } > > > "combase_test.d(51): function x overrides but is not covariant with x" > > > I strongly suspect that this is not just an omission, but something that has > been discussed and is a deliberate behaviour. If that is so, can someone enlighten me as to the rationale? > > :) > > Matthew > > |
August 30, 2003 Re: Co-variance reported with different calling convention | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | Well of course. We need a solution. I would very much like the following: 1. That Y.x is automatically deduced to be of type extern(Windows). Since D does not allow non-virtuals, this seems the best way. And consider what happens when Y is a template! Are we saying some superbly useful veneer template (to shamelessly use my own terminology) can be restricted to classes with matching methods of only one calling-convention? That totally sucks 2. A corollary is that calling convention should be "promoted" to something more inate in the language, so that I could write a template such as the following (in pseudo-C++, since my D templating is a little rusty): T is assumed to be an interface on which (pure virtual) lock() and unlock() methods are defined. We want a template that will work with any calling convention template <typename T> class ref_counter : public T { public: template<callconv C> extern (C) void C lock() { . . . } template<callconv C> extern (C) void C unlock() { . . . } }; Now this works with struct ICDeclRefCounter { virtual void __cdecl lock() = 0; virtual void __cdecl unlock() = 0; }; struct IStdCallRefCounter { virtual void __stdcall lock() = 0; virtual void __stdcall unlock() = 0; }; etc. etc. This is the most truculent imperfection in C++, and I f***ing hate it. It would be a stunning victory for D to handle this in the language proper, rather than having to use shims, or similar, workarounds. Nice challenge? ;) "Walter" <walter@digitalmars.com> wrote in message news:bip6lh$17hg$1@digitaldaemon.com... > The problem is that the calling conventions for X.x and Y.x are different, yet being virtual, they must have the same calling convention. > > "Matthew Wilson" <matthew@stlsoft.org> wrote in message news:bfj6h0$1cbf$1@digitaldaemon.com... > > > > class X > > { > > extern(Windows): > > void x() > > { > > printf("X::x()\n"); > > } > > } > > > > class Y > > : X > > { > > void x() > > { > > printf("Y::x()\n"); > > } > > } > > > > > > "combase_test.d(51): function x overrides but is not covariant with x" > > > > > > I strongly suspect that this is not just an omission, but something that > has > > been discussed and is a deliberate behaviour. If that is so, can someone enlighten me as to the rationale? > > > > :) > > > > Matthew > > > > > > |
August 30, 2003 Re: Co-variance reported with different calling convention | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matthew Wilson | Converting one calling convention to another would require the compiler to generate a function to do it, as in: int foo(int a, int b, int c) { int theotherfoo(int a, b, c); } Your item 1 may be the best solution. "Matthew Wilson" <matthew@stlsoft.org> wrote in message news:bipcba$1g74$1@digitaldaemon.com... > Well of course. We need a solution. > > I would very much like the following: > > 1. That Y.x is automatically deduced to be of type extern(Windows). Since D > does not allow non-virtuals, this seems the best way. And consider what happens when Y is a template! Are we saying some superbly useful veneer template (to shamelessly use my own terminology) can be restricted to classes with matching methods of only one calling-convention? That totally sucks > > 2. A corollary is that calling convention should be "promoted" to something > more inate in the language, so that I could write a template such as the following (in pseudo-C++, since my D templating is a little rusty): > > T is assumed to be an interface on which (pure virtual) lock() and > unlock() methods are defined. We want a template that will work with any > calling convention > > template <typename T> > class ref_counter > : public T > { > public: > template<callconv C> > extern (C) > void C lock() > { > . . . > } > template<callconv C> > extern (C) > void C unlock() > { > . . . > } > }; > > Now this works with > > struct ICDeclRefCounter > { > virtual void __cdecl lock() = 0; > virtual void __cdecl unlock() = 0; > }; > > struct IStdCallRefCounter > { > virtual void __stdcall lock() = 0; > virtual void __stdcall unlock() = 0; > }; > > etc. etc. > > This is the most truculent imperfection in C++, and I f***ing hate it. It would be a stunning victory for D to handle this in the language proper, rather than having to use shims, or similar, workarounds. > > Nice challenge? ;) > > > "Walter" <walter@digitalmars.com> wrote in message news:bip6lh$17hg$1@digitaldaemon.com... > > The problem is that the calling conventions for X.x and Y.x are different, > > yet being virtual, they must have the same calling convention. > > > > "Matthew Wilson" <matthew@stlsoft.org> wrote in message news:bfj6h0$1cbf$1@digitaldaemon.com... > > > > > > class X > > > { > > > extern(Windows): > > > void x() > > > { > > > printf("X::x()\n"); > > > } > > > } > > > > > > class Y > > > : X > > > { > > > void x() > > > { > > > printf("Y::x()\n"); > > > } > > > } > > > > > > > > > "combase_test.d(51): function x overrides but is not covariant with x" > > > > > > > > > I strongly suspect that this is not just an omission, but something that > > has > > > been discussed and is a deliberate behaviour. If that is so, can someone > > > enlighten me as to the rationale? > > > > > > :) > > > > > > Matthew > > > > > > > > > > > > |
Copyright © 1999-2021 by the D Language Foundation