D - Bug: Co-variance reported with different calling convention
- Matthew Wilson (22/22) Jul 22 2003 class X
- Matthew Wilson (4/7) Jul 22 2003 Of course, even if it deliberately cannot intuit the calling convention,...
- Russ Lewis (6/37) Jul 22 2003 I assume the problem is the same as if you had overloaded the function
- Matthew Wilson (13/50) Jul 24 2003 I get that. My point was that it either doesn't make sense, or is
- Farmer (12/33) Jul 28 2003 As you know, any occurence of class X must be substitutable for class Y.
- Matthew Wilson (3/5) Jul 29 2003 Please to hear it.
- Matthew Wilson (1/2) Jul 29 2003 Pleased to hear it, I meant
- Walter (5/27) Aug 29 2003 The problem is that the calling conventions for X.x and Y.x are differen...
- Matthew Wilson (50/87) Aug 29 2003 Well of course. We need a solution.
- Walter (14/104) Aug 30 2003 Converting one calling convention to another would require the compiler ...
- Riccardo De Agostini (5/12) Sep 01 2003 What about performance? Is it maybe better to explicitly enable, or bein...
- Walter (6/19) Sep 01 2003 to
- Matthew Wilson (7/27) Sep 01 2003 I don't want a compiler flag. I want the language to deduce the right
- Riccardo De Agostini (16/19) Sep 01 2003 flags
- Walter (6/25) Sep 02 2003 on
- Riccardo De Agostini (7/8) Sep 03 2003 While that may be a solution, or better a workaround, I don't think this...
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
Jul 22 2003
I strongly suspect that this is not just an omission, but something thathasbeen 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 ...)
Jul 22 2003
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
Jul 22 2003
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:hasclass 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 thatbeen discussed and is a deliberate behaviour. If that is so, can someone enlighten me as to the rationale? :) Matthew
Jul 24 2003
Hi Matthew, you wrote: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.class X { extern(Windows): void x() { printf("X::x()\n"); } } class Y : X { void x() { printf("Y::x()\n"); } }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.
Jul 28 2003
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.
Jul 29 2003
Please to hear it.Pleased to hear it, I meant
Jul 29 2003
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 thathasbeen discussed and is a deliberate behaviour. If that is so, can someone enlighten me as to the rationale? :) Matthew
Aug 29 2003
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 thathasbeen discussed and is a deliberate behaviour. If that is so, can someone enlighten me as to the rationale? :) Matthew
Aug 29 2003
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). SinceDdoes 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" tosomethingmore 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...different,The problem is that the calling conventions for X.x and Y.x arethatyet 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 somethingsomeonehasbeen discussed and is a deliberate behaviour. If that is so, canenlighten me as to the rationale? :) Matthew
Aug 30 2003
"Walter" <walter digitalmars.com> ha scritto nel messaggio news:biphsq$1o9r$1 digitaldaemon.com...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.What about performance? Is it maybe better to explicitly enable, or being able to disable, calling performance deduction via a compiler flag? Ric
Sep 01 2003
"Riccardo De Agostini" <riccardo.de.agostini email.it> wrote in message news:biuv93$nt2$1 digitaldaemon.com..."Walter" <walter digitalmars.com> ha scritto nel messaggio news:biphsq$1o9r$1 digitaldaemon.com...toConverting one calling convention to another would require the compilerWhile that's possible, I'm philosophically opposed to having compiler flags change the semantics of the language. There are innumerable such flags on typical C++ compilers, which cause endless problems.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.What about performance? Is it maybe better to explicitly enable, or being able to disable, calling performance deduction via a compiler flag?
Sep 01 2003
I don't want a compiler flag. I want the language to deduce the right behaviour for me. "Walter" <walter digitalmars.com> wrote in message news:biuvsu$on5$1 digitaldaemon.com..."Riccardo De Agostini" <riccardo.de.agostini email.it> wrote in message news:biuv93$nt2$1 digitaldaemon.com...compiler"Walter" <walter digitalmars.com> ha scritto nel messaggio news:biphsq$1o9r$1 digitaldaemon.com...Converting one calling convention to another would require thetobeinggenerate 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.What about performance? Is it maybe better to explicitly enable, orflagsable to disable, calling performance deduction via a compiler flag?While that's possible, I'm philosophically opposed to having compilerchange the semantics of the language. There are innumerable such flags on typical C++ compilers, which cause endless problems.
Sep 01 2003
"Walter" <walter digitalmars.com> ha scritto nel messaggio news:biuvsu$on5$1 digitaldaemon.com...While that's possible, I'm philosophically opposed to having compilerflagschange the semantics of the language. There are innumerable such flags on typical C++ compilers, which cause endless problems.I agree on that. How about defining a finite (and very small) set of language feature subsets, thus giving us only one switch to select the desired subset, in order to, for instance, compile for a slower target (typically an embedded system) being sure that what the compiler does under the hood doesn't result in performance loss in critical sections of the code? The need arises, funny enough, from one of the best features in DMD, i.e. being free of the virtual keyword, not to mention calling-convention polymorphism... OTOH, I realize that defining the subsets is a good starting point for holy wars :-) besides being, maybe, unpractical for other reasons. I'd really like feedback on this from people more experienced than I... Ric
Sep 01 2003
"Riccardo De Agostini" <riccardo.de.agostini email.it> wrote in message news:biv4q0$v71$1 digitaldaemon.com..."Walter" <walter digitalmars.com> ha scritto nel messaggio news:biuvsu$on5$1 digitaldaemon.com...onWhile that's possible, I'm philosophically opposed to having compilerflagschange the semantics of the language. There are innumerable such flagsundertypical C++ compilers, which cause endless problems.I agree on that. How about defining a finite (and very small) set of language feature subsets, thus giving us only one switch to select the desired subset, in order to, for instance, compile for a slower target (typically an embedded system) being sure that what the compiler doesthe hood doesn't result in performance loss in critical sections of the code?You can make a function 'final' and it will be non-virtual.The need arises, funny enough, from one of the best features in DMD, i.e. being free of the virtual keyword, not to mention calling-convention polymorphism... OTOH, I realize that defining the subsets is a good starting point forholywars :-) besides being, maybe, unpractical for other reasons. I'd really like feedback on this from people more experienced than I... Ric
Sep 02 2003
"Walter" <walter digitalmars.com> ha scritto nel messaggio news:bj334s$ecp$1 digitaldaemon.com...You can make a function 'final' and it will be non-virtual.While that may be a solution, or better a workaround, I don't think this is the purpose of "final" functions. Anyway, for the sake of consistent language semantics, I think I can live with automatic calling convention deduction after all. :) Ric
Sep 03 2003