CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11
  1. #1
    Join Date
    Jun 2002
    Location
    Germany
    Posts
    1,557

    [RESOLVED] Abstract or polymorphic classes w/out dtor

    Hello,

    I am investigating highly optimized, advanced C++ methods for tiny microcontroller systems. My investigations deal with systems which never exit --- they are switched on and switched off. This means that there will never be any kind of clean-up. Furthermore, my C++ libraries are specifically built and used with dummy implementations for after-main clean-up.

    So within this context, there are many objects for microcontrollers which are permanently present for the entire run-time of the program --- such as LCD displays, LED ports, Communication or timer peripherals, etc. These objects are declared once using a single instance without dynamic allocation. They always remain permanently present.

    So is it OK to optimize by removing virtual dtors for these types of objects? An example is shown below for a (simplified) abstract base class for an LED-port.

    Code:
      namespace hal
      {
        namespace led
        {
          struct Led //: private util::noncopyable
          {
          protected:
    
            Led() { }
            // No dtor? Is this OK for permanent, derived objects assuming no clean-up?
    
          public:
    
            virtual void Toggle(void) const = 0;
          }
        };
      }
    You're gonna go blind staring into that box all day.

  2. #2
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Abstract or polymorphic classes w/out dtor

    Does this really help, considering that you already have the cost of a virtual table?
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  3. #3
    Join Date
    Jun 2002
    Location
    Germany
    Posts
    1,557

    Re: Abstract or polymorphic classes w/out dtor

    Quote Originally Posted by laserlight View Post
    Does this really help, considering that you already have the cost of a virtual table?
    Yes, laserlight it does help. I am actually counting bytes for design methods for cost-sensitive systems. And the overall program code size (ROM/Flash) is, in fact, significantly smaller without the virtual dtor.

    In this case I have 4 "LedDerived" static singleton objects derived from the abstract base. If the code size is compared with the virtual dtor in the abstract base either present or absent, then the code size is 28-decimal bytes smaller per "LedDerived" object. For cost-sensitive, tiny applications with as little as 8kB or 16kB program code and which, nonetheless, take advantage of advanced C++ idioms, saving several tens of bytes P-code is a big thing.

    The difference is quite striking. I have been analyzing the map file. However, the mangled names of the automatically generated compiler subroutines are very confusing. I have not yet been able to understand exactly what the real differences are.

    I am using GCC cross compilers and binutils such as nm, readelf and objdump for these kinds of analyses.

    Sincerely, Chris.
    You're gonna go blind staring into that box all day.

  4. #4
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: Abstract or polymorphic classes w/out dtor

    Keep in mind that if derived classes don't have any extra parameters, and if you never destroy the object via base::~base, then you don't actually need virtual destructors at all.

    For example, vector derives from vector_base (in GCC), yet it does not have a virtual destructor. you are not supposed to handle vectors via vector_base.

    If in your case, the classes deriving from Led don't have new parameters (only re-define functions), then you can still safely destroy them non-virtually.

    This is usually not-recommended because of potential maintenance danger.

    That said, if you are in such a critical space-bound setup, there might be better alternatives to virtuals. I realize that virtuals are a good design help and you want to keep using them, which is fine, but you could still check on a per-object basis which solution is best.

    By using unions and enums (a union for the data according to class type, and an enum saying of which class this object is), I'm fairly sure you could reduce object size a lot. The draw back is probably bigger/slower compiled executable (more jumps), and harder to maintain code.

    Try to find out where the sweet spot is for each of your classes.
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

  5. #5
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Abstract or polymorphic classes w/out dtor

    An alternative to virtuals would be boost::variants. Variants can be made to never touch the heap if you put a few guarantees on your class, and they choose which function to call using a switch, which is usually faster than a virtual function call. The downside is that you need to define what a given function does for each type in one place, rather than defining how a given type handles each function in one place. This isn't always a bad thing, but it requires a different view of the problem.

  6. #6
    Join Date
    Jun 2002
    Location
    Germany
    Posts
    1,557

    Re: Abstract or polymorphic classes w/out dtor

    Quote Originally Posted by monarch_dodra View Post
    Keep in mind that if derived classes don't have any extra parameters, and if you never destroy the object via base::~base, then you don't actually need virtual destructors at all.

    ...

    If in your case, the classes deriving from Led don't have new parameters (only re-define functions), then you can still safely destroy them non-virtually.

    ...
    OK, Thanks monarch_dodra. I am actually describing a type of permanent object, each one of which is created in static memory not using dynamic allocation and each one of which will never be deleted. No dtors will ever be called for these kinds of objects.

    I think it is safe to remove virtual dtors, in fact to remove any and all dtors, for these special kinds of object-instances with such well-known constraints as I described. However, your first condition about added parameters in the derived class raises several questions. What if a derived Led obtains another parameter such as a color indication? Will I need a dtor or a virtual dtor even though the objects will never be deleted?

    The derived class LedColor below has added parameters (more than the base). Will it ever need a dtor or a virtual dtor if instances of it are never destroyed?

    Code:
    namespace hal
    {
      namespace led
      {
        struct Led : private util::noncopyable
        {
        protected:
    
          Led() { }
    
        public:
    
          virtual void Toggle(void) const = 0;
        };
    
        struct LedColor : public Led
        {
        public:
    
          typedef enum enum_color { orange, red, green } tColor;
    
        private:
    
          mutable bool is_on;
          const tColor color;
    
        protected:
    
          LedColor(const tColor c = orange) : is_on(false),
                                              color(c) { }
          // What about this? Any dtor needed here?
    
        private:
    
          virtual void Toggle(void) const { is_on = !is_on; }
    
        public:
    
          tColor GetColor(void) const { return color; }
        };
      }
    }
    Last edited by dude_1967; May 21st, 2010 at 01:46 PM. Reason: clarity improvements, corrections...
    You're gonna go blind staring into that box all day.

  7. #7
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Abstract or polymorphic classes w/out dtor

    If you don't intend to ever destroy the thing, then the question is moot.

    And virtual destructors are only needed if you want the code
    Code:
    Base *b = new Derived;
    delete b;
    to work properly.

  8. #8
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: Abstract or polymorphic classes w/out dtor

    If instances are never ever destroyed, then you don't really care about the destructors do you? Your answer is than yes, you may omit virtual destructors.

    What I was saying were general things that could be applied even if your objects are destroyed.

    That said, you can't completely remove the destructors, or your code will not compile. Default destructors are fine, just don't go trying to make non-destructable objects, that won't work.
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

  9. #9
    Join Date
    Jan 2009
    Posts
    1,689

    Re: Abstract or polymorphic classes w/out dtor

    If you're worried about space, why are you using C++? I haven't done any embedded programming in a few years, but last I knew C and MIPS still dominated, especially when constrained to something as tiny as 8Kb. The overhead of a vtable is worth mentioning here. Some modern programming techniques don't work when dealing with embedded systems because programmers usually consider memory to be limitless.
    Last edited by ninja9578; May 21st, 2010 at 02:10 PM.

  10. #10
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: Abstract or polymorphic classes w/out dtor

    Quote Originally Posted by ninja9578 View Post
    If you're worried about space, why are you using C++? I haven't done any embedded programming in a few years, but last I knew C and MIPS still dominated, especially when constrained to something as tiny as 8Kb. The overhead of a vtable is worth mentioning here. Some modern programming techniques don't work when dealing with embedded systems because programmers usually consider memory to be limitless.
    Well anything C can do, C++ can do just as good (For the same code). The problem is programmers using C++ features without fully considering the cost of said feature. That is why using C is a good choice, as it enforces your programmers to limit their use of complex (and potentially costly) features.

    If the OP is working alone on this project, and knows exactly what he is doing, then I'm sure a controlled C++ can be a good choice.

    Also, I'm fairly sure that while a C program will have a smaller executable than an equivalent C++ program (using C++ features, and especially if templates get involved), the stack space and object size should remain the same (data is data). Except for vtables I guess.

    That said, I have limited experience in embedded programming (I've veriloged FPGAs before, but that's not the same thing). So all I have is my software knowledge and my assumptions of how it fits into the embedded world. So your experience is probably more valuable than mine.
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

  11. #11
    Join Date
    Jun 2002
    Location
    Germany
    Posts
    1,557

    Re: Abstract or polymorphic classes w/out dtor

    Quote Originally Posted by Lindley View Post
    If you don't intend to ever destroy the thing, then the question is moot.
    After these kinds of clarifications, I guess so, thank you for the clarification.

    Quote Originally Posted by monarch_dodra
    If instances are never ever destroyed, then you don't really care about the destructors do you?
    I was not sure and I wanted to ask. I thought maybe in some way some specification or other implementation degree of freedom might have relied on (or at least not excluded) the existence of dtors.

    Quote Originally Posted by ninja9578
    If you're worried about space, why are you using C++? I haven't done any embedded programming in a few years, but last I knew C and MIPS still dominated, especially when constrained to something as tiny as 8Kb. The overhead of a vtable is worth mentioning here. Some modern programming techniques don't work when dealing with embedded systems because programmers usually consider memory to be limitless.
    Because I am investigating exactly these issues --- sorting out assumptions from fact and learning through hands-on experience when high-level abstractions are of advantage in embedded system design.

    I am in the fortunate position to benefit from over 20 years of experience with embedded system design and about 25 years of programming in a variety of languages. Off and on for the past few years, I have been looking at shrinking the footprint of C++ for embedded systems. I have done a rich set of investigations for two 32-bit processors and had some very good results in this area. At the present time, I am looking at even smaller C++ footprints for 8-bit systems while using even larger technologies and abstractions --- such as lambda functions with algorithms, quantifying the benefit/cost ratio of static polymorphism (templates) and dynamic polymorphism, as well a defining a subset of STL which is acceptable for tiny environments.

    I think this issue is cleared up now.

    Let me throw out a big Thanks to all the contributors for the helpful advice.

    Chris.
    You're gonna go blind staring into that box all day.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured