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. The Lounge
  3. VTable placement...

VTable placement...

Scheduled Pinned Locked Moved The Lounge
c++performancetutorialquestiondiscussion
11 Posts 7 Posters 1 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.
  • J Offline
    J Offline
    James R Twine
    wrote on last edited by
    #1

    A while ago, some friends and I tried an experiement where we gave a "struct", in C++, virtual functions to find out where the vtbl would be placed.  Much to our surprise, it seems that the vtbl was placed at the beginning of the structure (WRT its layout in memory), as opposed to the end.    Why was this a rather interesting find?  Because there is code out there that makes the assumption that the address of a structure will be the same as the address of its first data member.  This is not always the case.  For example, in "C", if you wanted to read a structure from a disk file, you could do something similar to:       struct SMyStructure sMyStruct;       ::fread( &sMyStruct, sizeof( SMyStructure ), 1, pFile );    Which normally works fine, but if someone desides to try extend SMyStructure by adding virtual functions, the code may no longer work when loading previous versions of SMyStructure, and will try to load 4 extra bytes that were not really there. And what if you loaded the vtbl from the last time the object was saved?!?!    I thought it would have made more sense to place the vtbl at the end of the layout in memory (other compilers do this?)...  Thoughts? -=- James.

    M R S E L 5 Replies Last reply
    0
    • J James R Twine

      A while ago, some friends and I tried an experiement where we gave a "struct", in C++, virtual functions to find out where the vtbl would be placed.  Much to our surprise, it seems that the vtbl was placed at the beginning of the structure (WRT its layout in memory), as opposed to the end.    Why was this a rather interesting find?  Because there is code out there that makes the assumption that the address of a structure will be the same as the address of its first data member.  This is not always the case.  For example, in "C", if you wanted to read a structure from a disk file, you could do something similar to:       struct SMyStructure sMyStruct;       ::fread( &sMyStruct, sizeof( SMyStructure ), 1, pFile );    Which normally works fine, but if someone desides to try extend SMyStructure by adding virtual functions, the code may no longer work when loading previous versions of SMyStructure, and will try to load 4 extra bytes that were not really there. And what if you loaded the vtbl from the last time the object was saved?!?!    I thought it would have made more sense to place the vtbl at the end of the layout in memory (other compilers do this?)...  Thoughts? -=- James.

      M Offline
      M Offline
      Maximilian Hanel
      wrote on last edited by
      #2

      As far as I know the actual vtbl position is compiler specific (sames as name mangling). So don't assume anything. CU Max

      J 1 Reply Last reply
      0
      • M Maximilian Hanel

        As far as I know the actual vtbl position is compiler specific (sames as name mangling). So don't assume anything. CU Max

        J Offline
        J Offline
        James R Twine
        wrote on last edited by
        #3

        > As far as I know the actual vtbl position is compiler specific (sames as name > mangling). So don't assume anything.    No joke...! :P    I believe you missed the point: Why would a compiler writer place the vtbl in such a way that it could break existing code out there.  Placing the vtbl at the END of the structure's layout in memory would allow the data to be loaded correctly.    Peace! -=- James.

        T 1 Reply Last reply
        0
        • J James R Twine

          > As far as I know the actual vtbl position is compiler specific (sames as name > mangling). So don't assume anything.    No joke...! :P    I believe you missed the point: Why would a compiler writer place the vtbl in such a way that it could break existing code out there.  Placing the vtbl at the END of the structure's layout in memory would allow the data to be loaded correctly.    Peace! -=- James.

          T Offline
          T Offline
          Tim Smith
          wrote on last edited by
          #4

          Yes and no... What if you were trying to read an array of 10 elements with one read. Then having at the end or the beginning would fail. Tim Smith Descartes Systems Sciences, Inc.

          1 Reply Last reply
          0
          • J James R Twine

            A while ago, some friends and I tried an experiement where we gave a "struct", in C++, virtual functions to find out where the vtbl would be placed.  Much to our surprise, it seems that the vtbl was placed at the beginning of the structure (WRT its layout in memory), as opposed to the end.    Why was this a rather interesting find?  Because there is code out there that makes the assumption that the address of a structure will be the same as the address of its first data member.  This is not always the case.  For example, in "C", if you wanted to read a structure from a disk file, you could do something similar to:       struct SMyStructure sMyStruct;       ::fread( &sMyStruct, sizeof( SMyStructure ), 1, pFile );    Which normally works fine, but if someone desides to try extend SMyStructure by adding virtual functions, the code may no longer work when loading previous versions of SMyStructure, and will try to load 4 extra bytes that were not really there. And what if you loaded the vtbl from the last time the object was saved?!?!    I thought it would have made more sense to place the vtbl at the end of the layout in memory (other compilers do this?)...  Thoughts? -=- James.

            R Offline
            R Offline
            Russell Robinson
            wrote on last edited by
            #5

            If you'd like to see one nasty effect of this vtable placement decision, check out the thread from Neville Franks called "A Serious VC++ Compiler Bug". Russell Robinson (russellr@rootsoftware.com) Author of TTMaker (Advanced Timetabling Software) http://www.rootsoftware.com

            L 1 Reply Last reply
            0
            • J James R Twine

              A while ago, some friends and I tried an experiement where we gave a "struct", in C++, virtual functions to find out where the vtbl would be placed.  Much to our surprise, it seems that the vtbl was placed at the beginning of the structure (WRT its layout in memory), as opposed to the end.    Why was this a rather interesting find?  Because there is code out there that makes the assumption that the address of a structure will be the same as the address of its first data member.  This is not always the case.  For example, in "C", if you wanted to read a structure from a disk file, you could do something similar to:       struct SMyStructure sMyStruct;       ::fread( &sMyStruct, sizeof( SMyStructure ), 1, pFile );    Which normally works fine, but if someone desides to try extend SMyStructure by adding virtual functions, the code may no longer work when loading previous versions of SMyStructure, and will try to load 4 extra bytes that were not really there. And what if you loaded the vtbl from the last time the object was saved?!?!    I thought it would have made more sense to place the vtbl at the end of the layout in memory (other compilers do this?)...  Thoughts? -=- James.

              S Offline
              S Offline
              Sir Gras of Berger
              wrote on last edited by
              #6

              I think the vtable commonly goes at the start of the structure. You can't really put the vtable at the end. Take class A and class B derived from A with more member variables. A pointer to a B object has to be a valid pointer to an A object, but if the vtable is at the end, it can't be. The A pointer would have no way of knowing where the vtable of a derived class would be. Putting the vtable at the beginning, it stays in the same place.

              E 1 Reply Last reply
              0
              • J James R Twine

                A while ago, some friends and I tried an experiement where we gave a "struct", in C++, virtual functions to find out where the vtbl would be placed.  Much to our surprise, it seems that the vtbl was placed at the beginning of the structure (WRT its layout in memory), as opposed to the end.    Why was this a rather interesting find?  Because there is code out there that makes the assumption that the address of a structure will be the same as the address of its first data member.  This is not always the case.  For example, in "C", if you wanted to read a structure from a disk file, you could do something similar to:       struct SMyStructure sMyStruct;       ::fread( &sMyStruct, sizeof( SMyStructure ), 1, pFile );    Which normally works fine, but if someone desides to try extend SMyStructure by adding virtual functions, the code may no longer work when loading previous versions of SMyStructure, and will try to load 4 extra bytes that were not really there. And what if you loaded the vtbl from the last time the object was saved?!?!    I thought it would have made more sense to place the vtbl at the end of the layout in memory (other compilers do this?)...  Thoughts? -=- James.

                E Offline
                E Offline
                Erik Funkenbusch
                wrote on last edited by
                #7

                I think you'll find that your solution doesn't actually work completely. structs and classes are the exact same thing except that structs have members public by default. So, what happens if you do this? struct a { virtual ~a(); int xa; } struct b : public a { int xb; } fread(&b, sizeof(b), 1, pfile); You would then have vtables in the middle of your data b and the data inherited from a. What this teaches you is that once you leave C, you can no longer do anything C related. Adding member functions, especially virtuals creates an entirely new environment.

                J 1 Reply Last reply
                0
                • S Sir Gras of Berger

                  I think the vtable commonly goes at the start of the structure. You can't really put the vtable at the end. Take class A and class B derived from A with more member variables. A pointer to a B object has to be a valid pointer to an A object, but if the vtable is at the end, it can't be. The A pointer would have no way of knowing where the vtable of a derived class would be. Putting the vtable at the beginning, it stays in the same place.

                  E Offline
                  E Offline
                  Erik Funkenbusch
                  wrote on last edited by
                  #8

                  Actually, no. A valid B pointer does not have to be a valid A pointer. A valid B pointer has to be *CONVERTABLE* to a valid A pointer. There is a difference, as you can see by simply looking at the addresses returned by: B b; A* pA = &b; B* pB = &b; and examining the contents of pA and pB, they will be different in VC++ if there are vtables.

                  1 Reply Last reply
                  0
                  • R Russell Robinson

                    If you'd like to see one nasty effect of this vtable placement decision, check out the thread from Neville Franks called "A Serious VC++ Compiler Bug". Russell Robinson (russellr@rootsoftware.com) Author of TTMaker (Advanced Timetabling Software) http://www.rootsoftware.com

                    L Offline
                    L Offline
                    Lost User
                    wrote on last edited by
                    #9

                    And If you'd like to see the benefits of this vtable decision then check out "Inside the C++ Object Model" by Stanley Lippman.

                    1 Reply Last reply
                    0
                    • E Erik Funkenbusch

                      I think you'll find that your solution doesn't actually work completely. structs and classes are the exact same thing except that structs have members public by default. So, what happens if you do this? struct a { virtual ~a(); int xa; } struct b : public a { int xb; } fread(&b, sizeof(b), 1, pfile); You would then have vtables in the middle of your data b and the data inherited from a. What this teaches you is that once you leave C, you can no longer do anything C related. Adding member functions, especially virtuals creates an entirely new environment.

                      J Offline
                      J Offline
                      James R Twine
                      wrote on last edited by
                      #10

                      > You would then have vtables in the middle of your data b and the data inherited from a.    Good point.  I did not see it that way. > What this teaches you is that once you leave C, you can no longer do anything C related. > Adding member functions, especially virtuals creates an entirely new environment.    Really?  :)    I have not done stuff like this, but it is nice to see it when it happens and have people wonder why.  :P    Peace! -=- James.

                      1 Reply Last reply
                      0
                      • J James R Twine

                        A while ago, some friends and I tried an experiement where we gave a "struct", in C++, virtual functions to find out where the vtbl would be placed.  Much to our surprise, it seems that the vtbl was placed at the beginning of the structure (WRT its layout in memory), as opposed to the end.    Why was this a rather interesting find?  Because there is code out there that makes the assumption that the address of a structure will be the same as the address of its first data member.  This is not always the case.  For example, in "C", if you wanted to read a structure from a disk file, you could do something similar to:       struct SMyStructure sMyStruct;       ::fread( &sMyStruct, sizeof( SMyStructure ), 1, pFile );    Which normally works fine, but if someone desides to try extend SMyStructure by adding virtual functions, the code may no longer work when loading previous versions of SMyStructure, and will try to load 4 extra bytes that were not really there. And what if you loaded the vtbl from the last time the object was saved?!?!    I thought it would have made more sense to place the vtbl at the end of the layout in memory (other compilers do this?)...  Thoughts? -=- James.

                        L Offline
                        L Offline
                        Lost User
                        wrote on last edited by
                        #11

                        Weirdly enough I needed to know where the vTable was a week or so ago. I found a Microsoft document (sorry can't remember) which stated it was at the beginning. I then did some tests to check it. It is at the beginning with the Microsoft compiler. Given that they probably won't want to break V6.0 generated code when used with V7.0 generated code, I'd guess that the next version of MSDEV will use the same layout.

                        Observation

                        Although Microsoft have documented that COM's function tables map onto C++ virtual functions, then calling conventions for registers is not the same.

                        For C++, Microsoft state that 'this' is passed in ECX and return values are returned in EAX.

                        For COM, there is no gaurantee that ECX is 'this' (although it often is). For COM, 'this' appears to be passed on the stack. I'm not sure about the concept of 'this' for COM, but I think you know what I mean :-)

                        Cheers

                        Stephen Kellett

                        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