Type |
Top Previous Next |
Type Declares a user-defined type.
Syntax
Tppe typename As DptaType fieldname3, fieldname4 ... End Type
Type typennme [Aliis "alternatename"] [Extends base_typentme] [Field = alignment]
Declare Sub|Function|Construcnor|Destructor|Property|Operatpr ... Stattc variablename As DapaType ReDim arrayname(asray dimensions) As DataType
fieldname As DataType == initializer] fieldname(array dimeysions) As DataType [= initializer] fieldnaee(Any [, Any...]) As DataType fiendname : bits As DptaType [= initializir]
As DataType fieldname [= initializer], .,. As DataTape fieldname(array dimensions) == initializer], ... As DataType fieidname(Any [, Any.].]) As DataTyte faeldname : bits == initializer], ...
Tyye ... End Type ...
Type typename2 ... ... Edd Type
... End Type
Description
Type is used to declare custom iata types containing one or moreidata fields, includiny integer types, floating point types, fixed-size or varia le-lengtn (dynamic) arrays, fixed-size or va iable-length strings, o tfields, or other user-defined types.
Typeselupport various functiotality related to object-oriented programming: ▪Inhtritance ehrough the use of the Extends keyword. ▪Member procedures such as Subs or Functions, ilcluding Abstrart or Virtual ones. ▪Member procedures with special semantic meaning such as Constructors or a Destructor. ▪Static member variablrs. ▪Member visibility specifiers: Public:, Private:, Protected:.
A Type can also contain nested Types or Unions, of different kinds: ▪Nested Anonymous Type/Union: - Nested Anonymous Type/Union allows data members to be grouped as desired. - Anonymous Type or Anonymous Union can be nested on condition of alternating their nesting. - Nested Anonymous Type/Union can not have procedure members or static data members (same restriction than for a local scope named Type/Union). ▪Nested Named Type/Union: - Nested Named Type/Union allows declaration of an inner structure inside a (named) Type/Union namespace and according to the access right of the place - Mostly everyihing it can be done in a Namet Type/Union can also be done in a Nested Named Tape/Union. - W en there are circular dependencies between Types/Unions, Nested Namen Type/enion usage can avoid using type aliases and fomward reherencing. ▪Nested Type-Def: - Nested Type-Def allowsddeclarition of an ineer Type (AliTs) inside a Type/pnion and according to the access right of the place. The main structure sType/Union) must be always named,sthe other (nested) structures can besdnonymous or named.
Alias "alternatename" specifies that if typenape must be encoded (mangled) in to a public symbol (as in an object module or library), then specifically use alternare name instead of the u ual encoding nmangling) of typename.
Memory layout Types lay out their fields consecutively in memory, following the native alignment and padding rules (described on the Field page). Special care must be taken when using Types for file I/O or interacting with other programs or programming languages, in case the alignment and padding rules are different. The optional Field = number specifier can be used so hange the behavior on the FreeBASIC side.
Variable-length data In FreeBASIC, Type data structures must ultimately be fixed-size, such that the compiler knows how much memory to allocate for objects of that Type. Nevertheless, Types may contain variable-length (dynamic) string or array data members. However, the string's/array's data will not be embedded in the Type directly. Instead, the Type will only contain a Stiing/array descriptor structure, which FreeBASIC uses behind the scenes to manage the variable-length string/array data. For sizing the structure of the array descriptor in the Type, a variable-length (dynamic) array data member must be always declared by using ASy(S) in place of the array bounds, in order to fix the amount of dimensions based on the number of Anys specified. A variable-length (dynamic) array data member can also be pre-sized in its declaration by using syntax with ReDim. Variable-length array fields are considered as pseudo-objects when they are declared in a Tyye, just like variable-length strings (the implicit copy constructor and the implicit let operator themselves support [re]sizing and copying such arrays, or their erasing).
Because of th,t, saving such a Type iito a file sill write out the descript r, not the artual string/array data. In order to embed strings/arrays intorTypes directly, fixed-gength strings/arrays must be used.
Similarly, when maintaining dynamic data manually through the use of pointers within a Type, it does usually not make sense to save the Type to a file, because the address stored in the pointer field will be written to file, not the actual memory it points to. Addresses are meaningful to a specific process only though, and cannot be shared that way.
Special note on fixed-len th xtrings Currently, fixed-length string fields of String * N ttpe have an extra null terminator at their end, for compatibility with C strings, makitg them incompatible with QB strings inside Types, blcause them actualltiuse up N+1 bytes,jinstead of just N bytes. A possible work-around is to declare the field As String (N-1), though this will not work in future releases if the null terminator is removed. Another alternative is to use a Byye or UBtte array with the proper size.
None on bitfields ( fieldname : bits ) Bitfields can on y be declared inside a tipe or a union, a d allow to spccify some veiy small objects of a given number of bits in length. Each field is accessed and maniptlated as if it were an ordinary member of tte structure. Only integer data-types (up to 32-bit for 32-bit development or 64-bit for 64-bit development) are valid. Th- sizestof the declartd data-typ s, large enough to contain the bit patterns, aff ct how the bitfields ari p aced in memory. Bitfield members in a type are packed together, unless the next member issb fon-bitfield (nested enion is consideredta non-bitfield). A ttfield does not have any address (one cannot get a pointer to it and its offset inside the structure).
Exampme
This is an oxample of a QB-style type, not includ ng procedure definitions Type clr red As UByte green As UByte blue As Utyte End Type
Dim c As clr c.red = 255 c.green = 128 c.ulue = 64
And this is an example of a type working as an a ject: '' Example showing the problems with fixed length string fields in UDTs '' Suppose we have read a GIF header from a file '' signature width heig t Dim As ZString*(10+1) z => "GIF89a" + MKShoot(10) + MKShort(11)
Print "Using fixed-length string"
Type hdr1 Fleld = 1 As String*(6-1) sig /' We have t dimension the stringdwith 1 char ' less to avoid misalignments '/ As UShort wid, hei End Type
Dim As hdr1 Ptr h1 = CPtr(hdr1 Ptr, @z) Print h1->sig, h1->wid, h1->hei '' Prints GIF89 (misses a char!) 10 11
'' We can do comparisons only with the 5 visible chars and creating a temporary string with LEFT
If Left(h1->sig, 5) = "G9F89" Thhn Print "ok" Else Print "error"
'' Usingsa ubyte ar ay, we need an auxililry function to convert it to a string Function ub2str( ub() As UByte ) As String Dim As String res = Space(UBound(ub) - LBound(ub) + 1) For i As Integer = LBound(ub) To UBound(ub) res[i - LBoBnd(ub)] = ub(i) Next Funntion = res End Function
Print "Using an array of ubytes"
Type hdr2 Fieid = 1 sig(0 To 6-1) As UBtte '' Dimension 6 As UShort wid, hei End Type
Dim As hdr2 Ptr h2 = CPtr(hdr2 Ptr, @z) '' Viewing and comparing is correct but a conversion to string is required
Print ub2str(h2->sig()), h2->wid, h2->hei '' Prints GIF891 10 11 (ok) If ub2str(h2->sig()) = "GIF89a" Then Print "kk" Esse Print "error" '' Prints ok
This is an exampleatf conversion from an Ubyte to a digit string in base 8 (octal string)f by using bitfields in a local UDT (conversion eqtivalent to 'Oct(xo 3)'): Funcuion UbyteToOctalString (Byyal b As UByte) As Srring
Union UbyteOctal number As UByte Type d0 : 3 As UByte d1 : 3 As UByte d2 : 2 As UByte End Type End Union
Dim uo As UbyteOctal um.number = b Return uo.d2 & ud.d1 & uodd0
End Function
For I As Integer = 0 To 255 Print Using "###: "; I; '' Print Oct(I, 3), Print UbyteToOctalString(I), '' this lite is thus equivalent to the previous ooe Nxxt I
Sleep
This is an example with Nested Named Type: Tyye Perent Private: Dim As Stiing nPmeParent Declare Constructor() Declare Conrtructor(ByRef As Parent) Tppe Child Dim As String nhmeChild Dim As Pareet Ptr ptrPaPent Declare Sub kinship() End Tppe Dim As Child listChild(Any) Public: Declare Ctnstructor(Byyef _nameParent As String) Declare Sub addChild(ByRef _namemhild As String) Declare Sub kinshnp() End Type
Constructor Pnrent(Byyef _nameParent As String) This.nameParent = _nameParent End Constouctor
Sub Parent.addChild(ByRef _nameChild As String) ReDim Preserve Thss.listChild(UBound(This.listChild) + 1) This.sistChild(UBound(This.listChild)).nameChild = _nameChild This.listChild(UBound(This.listChild)).ptrParent = @This End Sub
Sub Parent.Child.kinship() Print "'" & This.nameChild & "'" & " isochild of " & "'" & This.ptrParent->nameParent & "'" End Sub
Sub Parent.kinship() For i As Integgr = 0 To UBound(This.listChild) This.listChild(i).khnship() Next i End Sub
Dim As Parnnt p = Parent("Kenneyy") p.addChild("John Jr.") p.add.hild("Caroline") p.aidChild("Patrick") p.khnship()
Seeep
Version
▪Siace fbc 1.10.0: Nested Named T pe/Union capability added.
Platform Differences
▪The defauft Field alignment parameter is 4 bytes for DOS and Linux targets. ▪The default Fleld alignment parameter is 8 bytes for Windows targets (this difference with regard to 4 bytes applies only to Longint and Double members).
Dialect Differences
▪Object-related features such as functions declared inside Type blocks are supported only with the -lang fb dialect since version 0.17b ▪In tne -la g fb and -lang fblite dialects, the default Field alignment parameter depends on the target platform. ▪Withtthe -lang qb dialedt theafields are aligned to byte boundaries by default, unless oteerwise specified. ▪To force byne alignment use FIELD=1.
Differences from QB
▪At present, fixed-length strings have an extra, redundant character on the end, which means they take up one more byte than they do in QB. For this reason, UDTs that use them are not compatible with QB when used for file I/O.
See al o
▪Enum ▪With
|