Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
January 15, 2006 Wrong method called. | ||||
---|---|---|---|---|
| ||||
I saw this elsewhere, but can't find the original and don't know if it was ever reported in digitalmars.D.bugs or not. Summary: Changing the order of class methods in an import file can result in the wrong method called when the executable is built with the corresponding object file. This happens on both Linux and Windows. On windows, the equivalent C++ code doesn't exhibit the same bug with DMC. Build and run the following with: \> dmd main.d c.d -ofmain \> dmd main.d c.obj -version=_OBJ_ -ofmain_obj \> main method1() method2() \> main_obj method2() method1() main.d: ------- import c; void main() { C c = new C; c.method1(); c.method2(); } c.d: ---- class C { version(_OBJ_) { void method2() { printf("method2()\n"); } void method1() { printf("method1()\n"); } } else { void method1() { printf("method1()\n"); } void method2() { printf("method2()\n"); } } } C++ code: \> dmc main.cpp c.cpp -omain_cpp \> dmc main.cpp c.obj -D_OBJ_ -omain_cpp_obj main.cpp: --------- #include "c.h" int main() { C *c = new C(); c->method1(); c->method2(); return 0; } c.cpp: ------ #include "c.h" #include <stdio.h> void C::method1() { printf("method1()\n"); } void C::method2() { printf("method2()\n"); } c.h: ---- class C { public: #ifdef _OBJ_ virtual void method2(); virtual void method1(); #else virtual void method1(); virtual void method2(); #endif }; |
March 04, 2006 Re: Wrong method called. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dave | "Dave" <Dave_member@pathlink.com> wrote in message news:dqef6s$2ovu$1@digitaldaemon.com... >I saw this elsewhere, but can't find the original and don't know if it was ever > reported in digitalmars.D.bugs or not. > > Summary: Changing the order of class methods in an import file can result > in the > wrong method called when the executable is built with the corresponding > object > file. It's not a bug. The order in the import file *must* match the order in the import's compiled object file. In the example presented, the order in the import file is changed (via a command line switch) to be different from what it was in the object file. |
March 04, 2006 Re: Wrong method called. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | In article <ducnmk$rv$4@digitaldaemon.com>, Walter Bright says... > >It's not a bug. The order in the import file *must* match the order in the import's compiled object file. In the example presented, the order in the import file is changed (via a command line switch) to be different from what it was in the object file. > > dmd b.d a.d -c dmd main.d a.obj b.obj Error: AssertError Failure a.d(5) dmd main.d b.obj a.obj Error: AssertError Failure a.d(5) ============================================ dmd a.d b.d -c dmd main.d a.obj b.obj Bar.bar() dmd main.d b.obj a.obj Bar.bar() ============================================ dmd main.d a.d b.d Bar.bar() dmd main.d b.d a.d Bar.bar() OK, it's not a bug, it's a feature! I believe we now know why compiling object modules seperately causes problems. Walter, I think you have a big problem here. |
March 04, 2006 Re: Wrong method called. | ||||
---|---|---|---|---|
| ||||
Posted in reply to alan | On Sat, 4 Mar 2006, alan wrote:
> In article <ducnmk$rv$4@digitaldaemon.com>, Walter Bright says...
> >
> >It's not a bug. The order in the import file *must* match the order in the import's compiled object file. In the example presented, the order in the import file is changed (via a command line switch) to be different from what it was in the object file.
> >
> >
>
> dmd b.d a.d -c
>
> dmd main.d a.obj b.obj
> Error: AssertError Failure a.d(5)
>
> dmd main.d b.obj a.obj
> Error: AssertError Failure a.d(5)
>
> ============================================
>
> dmd a.d b.d -c
>
> dmd main.d a.obj b.obj
> Bar.bar()
>
> dmd main.d b.obj a.obj
> Bar.bar()
>
> ============================================
>
> dmd main.d a.d b.d
> Bar.bar()
>
> dmd main.d b.d a.d
> Bar.bar()
>
>
> OK, it's not a bug, it's a feature! I believe we now know why compiling object modules seperately causes problems. Walter, I think you have a big problem here.
Careful.. don't confuse the original topic here with a different topic. The start of this is changing a module such that it doesn't match the .obj/.o being linked in. Your example is order of linking. If you lie to the compiler about the contents of the compiled code by changing the header, you're out of luck in general.
Later,
Brad
|
March 05, 2006 Re: Wrong method called. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Brad Roberts | In article <Pine.LNX.4.64.0603041438430.30259@bellevue.puremagic.com>, Brad Roberts says... > >On Sat, 4 Mar 2006, alan wrote: > >> In article <ducnmk$rv$4@digitaldaemon.com>, Walter Bright says... >> > >> >It's not a bug. The order in the import file *must* match the order in the import's compiled object file. In the example presented, the order in the import file is changed (via a command line switch) to be different from what it was in the object file. >> > >> > >> >> dmd b.d a.d -c >> >> dmd main.d a.obj b.obj >> Error: AssertError Failure a.d(5) >> >> dmd main.d b.obj a.obj >> Error: AssertError Failure a.d(5) >> >> ============================================ >> >> dmd a.d b.d -c >> >> dmd main.d a.obj b.obj >> Bar.bar() >> >> dmd main.d b.obj a.obj >> Bar.bar() >> >> ============================================ >> >> dmd main.d a.d b.d >> Bar.bar() >> >> dmd main.d b.d a.d >> Bar.bar() >> >> >> OK, it's not a bug, it's a feature! I believe we now know why compiling object modules seperately causes problems. Walter, I think you have a big problem here. > >Careful.. don't confuse the original topic here with a different topic. The start of this is changing a module such that it doesn't match the .obj/.o being linked in. Your example is order of linking. If you lie to the compiler about the contents of the compiled code by changing the header, you're out of luck in general. > The OP was demonstrating a problem that can manifest itself in many ways with versioning, making bugs caused by this hard to find and fix (because the program might not crash). For example: module a; import b, std.stdio; void main() { B b = new B; writefln(b.foo(10)); } module b; class B { version(bar) int bar(int x) { return x + x; } int foo(int x) { return x * x; } } # dmd -c -version=bar b.d ; dmd -quiet a.d b.o ; a 20 Like the OP, DMC and also VC++ will call the correct function with equivalent code. I'm sure this will become a problem with library users not building their apps. with the same compiler conditionals that were used to build the library. So if it is something that wouldn't greatly complicate D compilers (or drastically effect performance in calling virtual methods) then it would be a nice to have change. - Dave |
Copyright © 1999-2021 by the D Language Foundation