c++ - problems with local classes
- John Smith (41/41) Sep 05 2006 Hi,
- Paul McKenzie (16/17) Sep 09 2006 Your code produces undefined behavior. The base class A does not have a
- John Smith (19/19) Sep 10 2006 The delete-parts of the code was actually an after-construction, added
- Bertel Brander (12/22) Sep 10 2006 Are you sure? I'm think it is perfectly legal to have a base class
- Paul McKenzie (10/17) Sep 10 2006 From the 1998 ANSI/ISO C++ Standard document.
- Bertel Brander (14/35) Sep 10 2006 I think you are right.
- Jan Knepper (7/56) Sep 11 2006 --
- John Smith (4/8) Sep 12 2006 No, I am not building it with any optimizations (that I know of). Just
Hi, I have been trying to compile (using 8.42n) some code using several local classes. But I have encountered problems with the dmc-compiler. Seems like the v-tables aren't stored correctly. Which in my case means that the right function isn't called at runtime. --- dmc_test.cpp --- #include <iostream> class A { public: virtual void a() = 0; }; int main() { { class B : public A { public: void a() { std::cout << "1"; } }; A * a = new B; a->a(); delete a; } { class B : public A { public: void a() { std::cout << "2"; } }; A * a = new B; a->a(); delete a; } return 0; } --- end of snippet --- This code compiles nicely, but gives the result "11" instead of the expected "12". Executables compiled with Mingw 3.4.5, Visual C++ 8.0, Borland C++ 5.6.4 and Open Watcom 1.5 all produces the expected output. John
Sep 05 2006
"John Smith" <no spam.com> wrote in message news:edlid4$gho$1 digitaldaemon.com...local classes. But I have encountered problems with the dmc-compiler.Your code produces undefined behavior. The base class A does not have a virtual destructor, therefore doing this: A *a = new B; //... delete a; // Error. invalidates the rest of the code. You cannot call "delete" on a base class pointer which is pointing to a derived class, unless the base class destructor is virtual. If it isn't virtual, the behavior is undefined (as per ANSI C++ specification -- don't have the time to look up chapter and verse). Change the A class to have a virtual destructor and see if the code works. Even if it doesn't work, you still need the virtual destructor for your code to really be a valid test of whether the compiler is working or not. Paul
Sep 09 2006
The delete-parts of the code was actually an after-construction, added when I posted it on the news-board (trying to avoid some irrelevant discussion.) The original code did not delete the objects, it just leaked them. Another way one is to explicitly cast it back to a B pointer in the delete-expression, and therefor fulfilling section 5.3.5.3, since the static and dynamic types are the same. Or I could just remove the dynamic allocation all together and write. B b; A * a = &b; a->a(); And I am sure there are other ways of writing this without using virtual destructors. But if we were to test out your version, we could even add the virtual destructors and see that it isn't even calling the right destructor. Since the problem is most likely related to the handling of the virtual-tables. The probability of the virtual destructors being the cause of the problem was pretty slim though, if you ask me ;) But thanks for pointing that out anyway. John
Sep 10 2006
Paul McKenzie wrote:"John Smith" <no spam.com> wrote in message news:edlid4$gho$1 digitaldaemon.com...Are you sure? I'm think it is perfectly legal to have a base class without any destructor. But if you want the destructor of the derevied class to be called upon deletion, if deleted through a base class pointer, you need a virtual destructor in the base class. But it is not undefined behaviour not to have one, the behaviour is perfectly defined; only the destructor of the base class (if any) is called. -- Just another homepage: http://damb.dk But it's mine - Bertellocal classes. But I have encountered problems with the dmc-compiler.Your code produces undefined behavior. The base class A does not have a virtual destructor, therefore doing this: A *a = new B; //... delete a; // Error.
Sep 10 2006
"Bertel Brander" <bertel post4.tele.dk> wrote in message news:ee1b50$1c37$1 digitaldaemon.com...Are you sure? I'm think it is perfectly legal to have a base class without any destructor. But if you want the destructor of the derevied class to be called upon deletion, if deleted through a base class pointer, you need a virtual destructor in the base class. But it is not undefined behaviour not to have one, the behaviour is perfectly defined; only the destructor of the base class (if any) is called.From the 1998 ANSI/ISO C++ Standard document. Section 5.3.5 (subsection 3): Delete: In the first alternative (delete object), if the static type of the operand is different from its dynamic type, the static type shall be a base class of the operand's dynamic type and the static type shall have a virtual destructor *or the behavior is undefined.* Paul
Sep 10 2006
Paul McKenzie wrote:"Bertel Brander" <bertel post4.tele.dk> wrote in message news:ee1b50$1c37$1 digitaldaemon.com...I think you are right. But way does all compilers then allow you to compile without a virtual destructor? Just after the section you quote it says: "In the second alternative (delete array) if the dynamic type of the object to be deleted differs from its static type, the behavior is undefined" This seems strange. Why can't you delete an array of a derived class through a pointer to a base class? -- Just another homepage: http://damb.dk But it's mine - BertelAre you sure? I'm think it is perfectly legal to have a base class without any destructor. But if you want the destructor of the derevied class to be called upon deletion, if deleted through a base class pointer, you need a virtual destructor in the base class. But it is not undefined behaviour not to have one, the behaviour is perfectly defined; only the destructor of the base class (if any) is called.From the 1998 ANSI/ISO C++ Standard document. Section 5.3.5 (subsection 3): Delete: In the first alternative (delete object), if the static type of the operand is different from its dynamic type, the static type shall be a base class of the operand's dynamic type and the static type shall have a virtual destructor *or the behavior is undefined.*
Sep 10 2006
Are you building with optimization on? John Smith wrote:Hi, I have been trying to compile (using 8.42n) some code using several local classes. But I have encountered problems with the dmc-compiler. Seems like the v-tables aren't stored correctly. Which in my case means that the right function isn't called at runtime. --- dmc_test.cpp --- #include <iostream> class A { public: virtual void a() = 0; }; int main() { { class B : public A { public: void a() { std::cout << "1"; } }; A * a = new B; a->a(); delete a; } { class B : public A { public: void a() { std::cout << "2"; } }; A * a = new B; a->a(); delete a; } return 0; } --- end of snippet --- This code compiles nicely, but gives the result "11" instead of the expected "12". Executables compiled with Mingw 3.4.5, Visual C++ 8.0, Borland C++ 5.6.4 and Open Watcom 1.5 all produces the expected output. John-- ManiaC++ Jan Knepper But as for me and my household, we shall use Mozilla... www.mozilla.org
Sep 11 2006
No, I am not building it with any optimizations (that I know of). Just plain "dmc dmc_test.cpp". I also tried both speed (-o) and space (-o+space) optimization-flags without any success. Jan Knepper wrote:Are you building with optimization on?
Sep 12 2006