Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. __interface implies the novtable __declspec modifier

__interface implies the novtable __declspec modifier

Scheduled Pinned Locked Moved C / C++ / MFC
csharpvisual-studioquestion
9 Posts 3 Posters 2 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    bob16972
    wrote on last edited by
    #1

    I'm just trying to understand the Microsoft specific modifier __interface. According to the MSDN, "__interface implies the novtable __declspec modifier." However, when I try to mock up code to try an verify this, Visual Studio 2008 still suggests the vtable pointer is present?

    __interface ISample
    {
    bool Next();
    bool Prev();
    };

    class CSample : public ISample
    {
    public:
    bool Next()
    {
    return false;
    }

    bool Prev()
    {
        return false;
    }
    

    };

    Am I misunderstanding what MSDN is trying to convey or am I just doing something wrong. In a nutshell, just trying to see if it's possible to enforce interface rules without needing the vtable overhead if only deriving from __interface declarations. I understand that this would not be portable code.

    H P 2 Replies Last reply
    0
    • B bob16972

      I'm just trying to understand the Microsoft specific modifier __interface. According to the MSDN, "__interface implies the novtable __declspec modifier." However, when I try to mock up code to try an verify this, Visual Studio 2008 still suggests the vtable pointer is present?

      __interface ISample
      {
      bool Next();
      bool Prev();
      };

      class CSample : public ISample
      {
      public:
      bool Next()
      {
      return false;
      }

      bool Prev()
      {
          return false;
      }
      

      };

      Am I misunderstanding what MSDN is trying to convey or am I just doing something wrong. In a nutshell, just trying to see if it's possible to enforce interface rules without needing the vtable overhead if only deriving from __interface declarations. I understand that this would not be portable code.

      H Offline
      H Offline
      H Brydon
      wrote on last edited by
      #2

      I have to think hard about this every time I look at this type of problem. I think the answer is that ISample is never concrete so it doesn't need a vtable. There is a vtable in CSample. When you call either of the 2 methods through a pointer (either CSample* or ISample*), the vtable needs are met by the concrete class.

      -- Harvey

      B 1 Reply Last reply
      0
      • B bob16972

        I'm just trying to understand the Microsoft specific modifier __interface. According to the MSDN, "__interface implies the novtable __declspec modifier." However, when I try to mock up code to try an verify this, Visual Studio 2008 still suggests the vtable pointer is present?

        __interface ISample
        {
        bool Next();
        bool Prev();
        };

        class CSample : public ISample
        {
        public:
        bool Next()
        {
        return false;
        }

        bool Prev()
        {
            return false;
        }
        

        };

        Am I misunderstanding what MSDN is trying to convey or am I just doing something wrong. In a nutshell, just trying to see if it's possible to enforce interface rules without needing the vtable overhead if only deriving from __interface declarations. I understand that this would not be portable code.

        P Offline
        P Offline
        pasztorpisti
        wrote on last edited by
        #3

        novtable is used in case of hardcore optimizations with "abstract" base classes are never instantiated. An interface is always abstract by definition. To understande novtable first you have to understand a bit more about how a derived class is instantiated and initialized. Let me explain this with a simple example:

        A
        

        / \
        B C
        / \
        D E

        The above drawing is a class hierarchy and we will examine the instantiation of the D class. Lets assume that A already has at least one virtual method so it has a vtable as well. What you have learnt about C++ is that "new D;" calls constructors A, C and D in this order. Now we delve into the implementation details and check out some interesting stuff. The simple truth is that the only thing that the compiler calls in case of "new D;" is the constructor of D. BUT every constructor starts with some auto generated stuff by the compiler that is followed by the "user defined constructor code". Let's see some pseudo code:

        constructor_D()
        {
        auto-generated: call constructor_C()
        auto-generated: init the vtable to vtable-D
        user-defined constructor code of D
        }

        constructor_C()
        {
        auto-generated: call constructor_A()
        auto-generated: init the vtable to vtable-C
        user-defined constructor code of C
        }

        constructor_A()
        {
        auto-generated: init the vtable to vtable-A
        user-defined constructor code of A
        }

        So if we consider only the "user defined constructor code" then the order of constructor calls is indeed A C D, but if we look at the whole stuff then its D C A. Its obvious that initializing the vtable more than once for an instance is superfluous, in the above example its initialzed 3 times, first in A, then in C and finially in D. We need the initialization only in D because we created a D instance so we need the virtual methods for the D class. Unfortunately sometimes the compiler can not find out whether the vtable initialization in A and C are superfluous or not so it generates the vtable init code there, but you can add the novtable to class A and C as an optimization if you know that they will never be instantiated. In case of an interface we know that it will never be instantiated so an automatic novtable optimization is obvious, an interface will have at least one descendant to init the final vtable pointer. In your example the ISample interface simply doesn't have a constructor and your CSample constructor looks like this:

        B H 2 Replies Last reply
        0
        • H H Brydon

          I have to think hard about this every time I look at this type of problem. I think the answer is that ISample is never concrete so it doesn't need a vtable. There is a vtable in CSample. When you call either of the 2 methods through a pointer (either CSample* or ISample*), the vtable needs are met by the concrete class.

          -- Harvey

          B Offline
          B Offline
          bob16972
          wrote on last edited by
          #4

          Thanks for responding. I guess my confusion is if __interface hints to the compiler that the base class will never be instantiated, even though __interface supposedly makes the methods pure virtual, I was hoping that the interface rules were being enforced at compile time and the virtualness of the base class declarations would not propagate up to the derived class, unless of course the derived class explicitly declared something virtual. I know that kinda flies in the face of the normal rules for virtual but I was hoping there was a way to get interface rules enforcement without literally applying the virtual rules unless explicit outside of the interface. I was hoping that CSample, in this case, would be treated at runtime like it did not have a base class and did not have any virtual methods, and thus the compiler would discard the vtable for it as well. Is the vtable really needed (in this scenario)?

          1 Reply Last reply
          0
          • P pasztorpisti

            novtable is used in case of hardcore optimizations with "abstract" base classes are never instantiated. An interface is always abstract by definition. To understande novtable first you have to understand a bit more about how a derived class is instantiated and initialized. Let me explain this with a simple example:

            A
            

            / \
            B C
            / \
            D E

            The above drawing is a class hierarchy and we will examine the instantiation of the D class. Lets assume that A already has at least one virtual method so it has a vtable as well. What you have learnt about C++ is that "new D;" calls constructors A, C and D in this order. Now we delve into the implementation details and check out some interesting stuff. The simple truth is that the only thing that the compiler calls in case of "new D;" is the constructor of D. BUT every constructor starts with some auto generated stuff by the compiler that is followed by the "user defined constructor code". Let's see some pseudo code:

            constructor_D()
            {
            auto-generated: call constructor_C()
            auto-generated: init the vtable to vtable-D
            user-defined constructor code of D
            }

            constructor_C()
            {
            auto-generated: call constructor_A()
            auto-generated: init the vtable to vtable-C
            user-defined constructor code of C
            }

            constructor_A()
            {
            auto-generated: init the vtable to vtable-A
            user-defined constructor code of A
            }

            So if we consider only the "user defined constructor code" then the order of constructor calls is indeed A C D, but if we look at the whole stuff then its D C A. Its obvious that initializing the vtable more than once for an instance is superfluous, in the above example its initialzed 3 times, first in A, then in C and finially in D. We need the initialization only in D because we created a D instance so we need the virtual methods for the D class. Unfortunately sometimes the compiler can not find out whether the vtable initialization in A and C are superfluous or not so it generates the vtable init code there, but you can add the novtable to class A and C as an optimization if you know that they will never be instantiated. In case of an interface we know that it will never be instantiated so an automatic novtable optimization is obvious, an interface will have at least one descendant to init the final vtable pointer. In your example the ISample interface simply doesn't have a constructor and your CSample constructor looks like this:

            B Offline
            B Offline
            bob16972
            wrote on last edited by
            #5

            Thanks for taking the time for such a detailed response. It got me thinking about it some more and I believe I now understand why it's there. I was just hoping that the vtable wasn't even needed if the instantiated classes didn't explicitly declare anything virtual. I was hoping the __interface rules and requirements could all be enforced at compile time and the need for the vtable in the derived class could be discarded in my scenario. Do you think if a true interface keyword existed in the C++ standard, that the virtualness of the interface would not be implied in the classes that "implement" the interfaces. Do "deriving from the interface" and "implementing the interface" mean the same thing?

            P 1 Reply Last reply
            0
            • B bob16972

              Thanks for taking the time for such a detailed response. It got me thinking about it some more and I believe I now understand why it's there. I was just hoping that the vtable wasn't even needed if the instantiated classes didn't explicitly declare anything virtual. I was hoping the __interface rules and requirements could all be enforced at compile time and the need for the vtable in the derived class could be discarded in my scenario. Do you think if a true interface keyword existed in the C++ standard, that the virtualness of the interface would not be implied in the classes that "implement" the interfaces. Do "deriving from the interface" and "implementing the interface" mean the same thing?

              P Offline
              P Offline
              pasztorpisti
              wrote on last edited by
              #6

              "deriving from the interface" and "implementing the interface" are basically the same, the only subtle difference is that you usually say "implement" (but "derive" or "extend" are also okay) when the base class is an interface - the only exception is when both the subclass and the base class are interfaces because in this case documentations use "extend" or "derive". This because evident after reading some documentation about C# or java where there is sharp distinction between classes and interfaces, the VS __interface keyword is also something that mimics the behavior of C# interfaces. What do you mean on "virtualness" of the class that implements the interface?

              B 1 Reply Last reply
              0
              • P pasztorpisti

                "deriving from the interface" and "implementing the interface" are basically the same, the only subtle difference is that you usually say "implement" (but "derive" or "extend" are also okay) when the base class is an interface - the only exception is when both the subclass and the base class are interfaces because in this case documentations use "extend" or "derive". This because evident after reading some documentation about C# or java where there is sharp distinction between classes and interfaces, the VS __interface keyword is also something that mimics the behavior of C# interfaces. What do you mean on "virtualness" of the class that implements the interface?

                B Offline
                B Offline
                bob16972
                wrote on last edited by
                #7

                pasztorpisti wrote:

                What do you mean on "virtualness" of the class that implements the interface?

                Sorry, just meaning that once declared virtual in base class, a method is virtual for all "derived" classes.

                1 Reply Last reply
                0
                • P pasztorpisti

                  novtable is used in case of hardcore optimizations with "abstract" base classes are never instantiated. An interface is always abstract by definition. To understande novtable first you have to understand a bit more about how a derived class is instantiated and initialized. Let me explain this with a simple example:

                  A
                  

                  / \
                  B C
                  / \
                  D E

                  The above drawing is a class hierarchy and we will examine the instantiation of the D class. Lets assume that A already has at least one virtual method so it has a vtable as well. What you have learnt about C++ is that "new D;" calls constructors A, C and D in this order. Now we delve into the implementation details and check out some interesting stuff. The simple truth is that the only thing that the compiler calls in case of "new D;" is the constructor of D. BUT every constructor starts with some auto generated stuff by the compiler that is followed by the "user defined constructor code". Let's see some pseudo code:

                  constructor_D()
                  {
                  auto-generated: call constructor_C()
                  auto-generated: init the vtable to vtable-D
                  user-defined constructor code of D
                  }

                  constructor_C()
                  {
                  auto-generated: call constructor_A()
                  auto-generated: init the vtable to vtable-C
                  user-defined constructor code of C
                  }

                  constructor_A()
                  {
                  auto-generated: init the vtable to vtable-A
                  user-defined constructor code of A
                  }

                  So if we consider only the "user defined constructor code" then the order of constructor calls is indeed A C D, but if we look at the whole stuff then its D C A. Its obvious that initializing the vtable more than once for an instance is superfluous, in the above example its initialzed 3 times, first in A, then in C and finially in D. We need the initialization only in D because we created a D instance so we need the virtual methods for the D class. Unfortunately sometimes the compiler can not find out whether the vtable initialization in A and C are superfluous or not so it generates the vtable init code there, but you can add the novtable to class A and C as an optimization if you know that they will never be instantiated. In case of an interface we know that it will never be instantiated so an automatic novtable optimization is obvious, an interface will have at least one descendant to init the final vtable pointer. In your example the ISample interface simply doesn't have a constructor and your CSample constructor looks like this:

                  H Offline
                  H Offline
                  H Brydon
                  wrote on last edited by
                  #8

                  Excellent answer, better than mine. +5 for yours...

                  -- Harvey

                  P 1 Reply Last reply
                  0
                  • H H Brydon

                    Excellent answer, better than mine. +5 for yours...

                    -- Harvey

                    P Offline
                    P Offline
                    pasztorpisti
                    wrote on last edited by
                    #9

                    Thank you!

                    1 Reply Last reply
                    0
                    Reply
                    • Reply as topic
                    Log in to reply
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes


                    • Login

                    • Don't have an account? Register

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • World
                    • Users
                    • Groups