Microsoft KB Archive/249962

From BetaArchive Wiki
< Microsoft KB Archive
Revision as of 12:51, 21 July 2020 by X010 (talk | contribs) (Text replacement - """ to """)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Knowledge Base


INFO: Differences in Padding UDTs Between Visual Basic 5 and Visual Basic 6

Article ID: 249962

Article Last Modified on 5/12/2003



APPLIES TO

  • Microsoft Visual Basic 5.0 Learning Edition
  • Microsoft Visual Basic 6.0 Learning Edition
  • Microsoft Visual Basic 5.0 Professional Edition
  • Microsoft Visual Basic 6.0 Professional Edition
  • Microsoft Visual Basic 5.0 Enterprise Edition
  • Microsoft Visual Basic 6.0 Enterprise Edition



This article was previously published under Q249962

SUMMARY

The amount of memory allocated for a UDT in Visual Basic can be different in Visual Basic 6.0 and Visual Basic 5.0 depending on the data types used in the UDT and their order.

MORE INFORMATION

Both Visual Basic 5.0 and Visual Basic 6.0 use an alignment factor of 4. This means that every element of a UDT must start on a byte which is a multiple of the size of the element itself or a multiple of the alignment factor, whichever is less. For example, an element of type Integer must start on a byte address that is a multiple of 2, while an element of type Double must start on a byte address that is a multiple of 4.

In addition, some compilers add padding bytes at the end of the UDT to make the size of the UDT a multiple of the alignment factor or a multiple of the largest data size used in the structure, whichever is less. For example, a UDT in which the largest data type is an Integer should have the total size of the UDT a multiple of 2 while an UDT in which the largest data type is a Double should have a size multiple of 4.

The difference between Visual Basic 5.0 and Visual Basic 6.0 is that the Visual Basic 5.0 compiler only adds the required padding if you use an array of UDTs while the Visual Basic 6.0 compiler (and the C compiler) always do it regardless of whether or not you are using an array of structures. The Visual Basic 6.0 approach is consistent with the C approach.

Programmers who use only Visual Basic, or who don't pass UDTs to functions written in other languages don't have to take this into consideration. However, programmers passing UDTs to functions written in other languages should understand this difference and evaluate how this can affect their applications.

The following sample project demonstrates this difference:

  1. Create a new Standard EXE project. Form1 is created by default
  2. In the Project menu, select Add Module. Module1 will be created.
  3. In Module1, add the following code:

    Option Explicit
    Type Type1
        m as Long
        i as Integer
    End Type
    
    Type Type2
        m as Long
        t1 as Type1
        i as Integer
    End Type
    
    Type Type3
        t1(0) as Type1
    End Type
    
                        
  4. On Form1, add a CommandButton.
  5. On the Command1_Click event, add the following code:

    Dim t1 as Type1
    Dim t2 as Type2
    Dim t3 as Type3
    
    MsgBox "Size of Type1 is: " & LenB(t1) 
    MsgBox "Size of Type2 is: " & LenB(t2) 
    MsgBox "Size of Type3 is: " & LenB(t3) 
                        

Run the project to see the size of each structure. You should see the following results:

Type VB5 VB6
Type1 6 8
Type2 12 16
Type3 8 8



Potential problems:

The problem arises in Visual Basic 5.0 when you pass a structure of Type2 to a function written in C because the C compiler assumes Type1 as being of size 8 while Visual Basic 5.0 assumes size 6. The problem in this case is with the 3rd member of the structure (element i). In Visual Basic this member starts at the 11th byte of the structure while the C compiler assumes it to start at the 13th byte.

Workaround:

One possible workaround is to add filler elements at the end of the structure to make the size in Visual Basic match the size in C. In the preceeding case you could define the UDTs as follows:

Type Type1
    m as Long
    i as Integer
    filler as Integer ' added to match UDT's size
End Type

 Type Type2
    m as Long
    t1 as Type1
    i as Integer
    filler as Integer ' added to match UDT's size
End Type
                


Additional query words: UDType

Keywords: kbinfo kbinterop KB249962