diff --git a/doc/manual/cache/CatPgFunctIndex.wakka b/doc/manual/cache/CatPgFunctIndex.wakka index 8ee028a199..9b05bfe7e9 100644 --- a/doc/manual/cache/CatPgFunctIndex.wakka +++ b/doc/manual/cache/CatPgFunctIndex.wakka @@ -408,7 +408,7 @@ List of ""FreeBASIC"" keywords sorted by the function they perform. - {{fbdoc item="keyword" value="KeyPgDdfbdos|__FB_DOS__"}} - {{fbdoc item="keyword" value="KeyPgDdfberr|__FB_ERR__"}} - {{fbdoc item="keyword" value="KeyPgDdfbfpmode|__FB_FPMODE__"}} - - {{fbdoc item="keyword" value="KeyPgDdfbfpu|__FB_FPFPU__"}} + - {{fbdoc item="keyword" value="KeyPgDdfbfpu|__FB_FPU__"}} - {{fbdoc item="keyword" value="KeyPgDdfbfreebsd|__FB_FREEBSD__"}} - {{fbdoc item="keyword" value="KeyPgDdfbgcc|__FB_GCC__"}} - {{fbdoc item="keyword" value="KeyPgDdfbgui|__FB_GUI__"}} diff --git a/doc/manual/cache/DevBootstrap.wakka b/doc/manual/cache/DevBootstrap.wakka index b26e70bab5..d88857ac12 100644 --- a/doc/manual/cache/DevBootstrap.wakka +++ b/doc/manual/cache/DevBootstrap.wakka @@ -6,12 +6,29 @@ fbc is written in FB itself, so you need a working fbc to build a new fbc. How t The ""FreeBASIC-x.xx.x-source-bootstrap"" package contains the FB sources plus precompiled compiler sources, for multiple targets. After extracting, this can be built without requiring an existing fbc: %%make bootstrap%% - (as long as the package contains the precompiled sources for the target system) This package can be created by running: %%make bootstrap-dist%% +{{fbdoc item="section" value="Bootstrapping by creating and using a bootstrap package"}} + + 1) On a system with a working fbc compiler, create the bootstrap package: + %%make bootstrap-dist%% + creates ##FreeBASIC-x.xx.x-source-bootstrap.tar.xz## + + 1) Take the bootstrap package to the new system and use it to build the bootstrap compiler: + %%cd ~ +tar xf ~/FreeBASIC-x.xx.x-source-bootstrap.tar.xz +cd FreeBASIC-x.xx.x-source-bootstrap +make bootstrap +%% + + 1) On the new system, assuming sources are in ~/fbc, use the bootstrap compiler to build fbc for the new system + %%cd ~/fbc +make 'FBC=~/FreeBASIC-x.xx.x-source-bootstrap/bin/fbc -i ~/FreeBASIC-x.xx.x-source-bootstrap/inc' +%% + Doing ##make bootstrap-dist##, taking the package to the target system, and then doing ##make bootstrap## can replace the manual steps below, as long as the target is already supported by these commands in the FB makefile. {{fbdoc item="section" value="Bootstrapping by precompiling the compiler sources"}} diff --git a/doc/manual/cache/KeyPgAlias.wakka b/doc/manual/cache/KeyPgAlias.wakka index 2666d63eb4..e695f202cb 100644 --- a/doc/manual/cache/KeyPgAlias.wakka +++ b/doc/manual/cache/KeyPgAlias.wakka @@ -1,5 +1,5 @@ {{fbdoc item="title" value="ALIAS"}}---- -Clause of the ##[[KeyPgSub|Sub]]## and ##[[KeyPgFunction|Function]]## statements that provides an alternate internal name +Clause of the ##[[KeyPgSub|Sub]]## and ##[[KeyPgFunction|Function]]## statements that provides an alternate internal name. {{fbdoc item="syntax"}}## [[[KeyPgDeclare|declare]]] { [[KeyPgSub|sub]] | [[KeyPgFunction|function]] } //usablename// **Alias "//alternatename//"** (...) @@ -23,6 +23,8 @@ Clause of the ##[[KeyPgSub|Sub]]## and ##[[KeyPgFunction|Function]]## statements ##Alias## is commonly used for procedures in libraries written in other languages when such procedure names are valid in the other language but invalid in BASIC. When using ##Alias## with ##[[KeyPgDeclare|Declare]]##, only the alternate name is used by the linker. Differently from normal procedure names, ##Alias## does not change the case of the alternate name, so it is useful when external code requires an exported function with a particular name or with a particular case. + + ##Alias## can also be used as modifier that specifies an alternate mangling for procedure parameters. For example ##extern ""c+""""+"" : declare sub proc( byval as long **alias "long"** ) : end extern##. This form of ##Alias## can only be used as in //##[unsigned] [u]long alias "long"##//. The specific purpose is to allow FreeBASIC to call external ""c+""""+"" procedures (on win-64) requiring a 32-bit ##'long int'## type. Usage of ##Alias## in this way affects win-64 targets only, and is ignored on all other targets. {{fbdoc item="ex"}} diff --git a/doc/manual/cache/KeyPgDdfbgui.wakka b/doc/manual/cache/KeyPgDdfbgui.wakka new file mode 100644 index 0000000000..16e88b4b19 --- /dev/null +++ b/doc/manual/cache/KeyPgDdfbgui.wakka @@ -0,0 +1,29 @@ +{{fbdoc item="title" value="__FB_GUI__"}}---- +Intrinsic define (macro value) set by the compiler + +{{fbdoc item="syntax"}}## + ""__FB_GUI__"" +## +{{fbdoc item="desc"}} + ##""__FB_GUI__""## indicates if the executable subsystem option '-s gui' was specified on the command line at the time of compilation. + + Returns non-zero (-1) if the executable subsystem option '-s gui' was specified. Returns zero (0) otherwise (no executable subsystem option specified, or executable subsystem option '-s console' specified). + +{{fbdoc item="ex"}} +{{fbdoc item="filename" value="examples/manual/defines/fbgui.bas"}}%%(freebasic) +#if __FB_GUI__ <> 0 + #print Executable subsystem: gui +#else + #print Executable subsystem: console +#endif +%% +{{fbdoc item="target"}} + - Supported on Windows and Cygwin only. + +{{fbdoc item="diff"}} + - New to ""FreeBASIC"" + +{{fbdoc item="see"}} + - [[CompilerOpts|Compiler Option: -s]] + +{{fbdoc item="back" value="CatPgDddefines|Intrinsic Defines"}} \ No newline at end of file diff --git a/doc/manual/cache/KeyPgModuleConstructor.wakka b/doc/manual/cache/KeyPgModuleConstructor.wakka index 4201d520e0..dbe1b41b59 100644 --- a/doc/manual/cache/KeyPgModuleConstructor.wakka +++ b/doc/manual/cache/KeyPgModuleConstructor.wakka @@ -11,15 +11,23 @@ Specifies execution of a procedure before module-level code The procedure must have an empty parameter list. A compile-time error will be generated if the ##**Constructor**## keyword is used in a Sub definition having one or more parameters. In a set of overloaded procedures, only one (1) constructor may be defined because of the ambiguity of having multiple Subs which take no arguments. - In a single module, constructors normally execute in the reverse order in which they are defined. + In a single module, depending on the build and run-time environment of the target system: + - constructors may execute in which they are defined, or reverse order + - constructors may execute before or after global static variables having constructors + - constructors may execute before or after other module constructors having ##//priority//## attribute + - constructors with ##//priority//## attribute may execute before or after global static variables having constructors - The ##//priority//## attribute, an integer between 101 and 65535, can be used to force constructors to be executed in a certain order. The value of ##//priority//## has no specific meaning, only the relationship of the number with other constructor priorities. 101 is the highest priority and is executed first. All constructors having a ##//priority//## attribute are executed before constructors with no attribute. The priority value of 65535 is the same as not assigning a priority value. + The ##//priority//## attribute, an integer between 101 and 65535, can be used to force constructors to be executed in a certain order, relative to other constructors also having ##//priority//## attribute. The value of ##//priority//## has no specific meaning, only the relationship of the number with other constructor priorities. 101 is the highest priority and is executed first, relative to other constructors also having ##//priority//## attribute. A module may define multiple constructor procedures, and multiple modules may define additional constructors provided no two ##[[KeyPgPublic|Public]]## constructors share the same //procedure_name//. When linking with modules that also define constructors, the order of execution is not guaranteed at link-time unless the ##//priority//## attribute is used. Therefore, special care should be taken when using constructors that may call on a secondary module also defining a constructor. In such a case it is advisable to use a single constructor that explicitly calls initialization procedures in those modules. - **Note:** A public static member procedure (Sub having empty parameter list) can also be defined as module constructor (also with the ##**Constructor**## keyword only used in Sub definition). + Public static member procedures (a ##[[KeyPgMemberSub|Sub]]## having an empty parameter list), of user defined ##[[KeyPgType|type]]## can be defined as a module constructor, by adding the ##**Constructor**## keyword used in the sub procedure definition. + + Initialization of static simple numeric type variables, that have a value that can be determined at compile time (for example, default zero, constants, pointers to static objects, pointers to functions, etc), are initialized before any code is executed. These values are part of the executable image and have an initial value when the executable is loaded in to memory. Trivial static globals where no code is needed to initialize, are guaranteed to be initialized and can be reliably used in all code, including global static object constructors and module constructors. + + The module constructor feature exposes a low-level link-time feature of the build and run-time environment. Accessing global static objects having constructors from module constructors should be avoided due to variations in execution order on different build systems. {{fbdoc item="ex"}} {{fbdoc item="filename" value="examples/manual/procs/mod-ctor.bas"}}%%(freebasic) diff --git a/doc/manual/cache/KeyPgModuleDestructor.wakka b/doc/manual/cache/KeyPgModuleDestructor.wakka index 15a99f0b05..6c19690043 100644 --- a/doc/manual/cache/KeyPgModuleDestructor.wakka +++ b/doc/manual/cache/KeyPgModuleDestructor.wakka @@ -11,15 +11,23 @@ Specifies execution of a procedure at program termination The procedure must have an empty parameter list. A compile-time error will be generated if the ##**Destructor**## keyword is used in a Sub definition having one or more parameters. In a set of overloaded procedures, only one (1) destructor may be defined because of the ambiguity of having multiple Subs which take no arguments. - In a single module, destructors normally execute in the order in which they are defined. + In a single module, depending on the build and run-time environment of the target system: + - destructors may execute in which they are defined, or reverse order + - destructors may execute before or after global static variables having dstructors + - destructors may execute before or after other module destructors having ##//priority//## attribute + - destructors with ##//priority//## attribute may execute before or after global static variables having destructors - The ##//priority//## attribute, an integer between 101 and 65535, can be used to force destructors to be executed in a certain order. The value of ##//priority//## has no specific meaning, only the relationship of the number with other destructor priorities. 101 is the lowest priority and is executed last. All destructors having a ##//priority//## attribute are executed after destructors with no attribute. The priority value of 65535 is the same as not assigning a priority value. + The ##//priority//## attribute, an integer between 101 and 65535, can be used to force destructors to be executed in a certain order. The value of ##//priority//## has no specific meaning, only the relationship of the number with other destructor priorities. 101 is the lowest priority and is executed last, relative to other destructors also having ##//priority//## attribute. A module may define multiple destructor procedures. Destructor procedures may also appear in more than one module. All procedures defined with the syntax shown above will be added to the list of procedures to be called during the program's termination. The order in which destructors defined in multiple modules are executed is known only at link time. Therefore, special care should be taken when using destructors that may call on a secondary module also defining a destructors. In such a case it is advisable to use a single destructor that explicit calls termination procedures in multiple modules to ensure a graceful termination of the application. Destructors will be called if the program terminates normally or if error-checking is enabled and the program terminates abnormally. + + Public static member procedures (a ##[[KeyPgMemberSub|Sub]]## having an empty parameter list), of user defined ##[[KeyPgType|type]]## can be defined as a module destructor, by adding the ##**Constructor**## keyword used in the sub procedure definition. + + The module destructor feature exposes a low-level link-time feature of the build and run-time environment. Accessing global static objects having destructors from module destructors should be avoided due to variations in execution order on different build systems. {{fbdoc item="ex"}} {{fbdoc item="filename" value="examples/manual/procs/mod-dtor.bas"}}%%(freebasic) diff --git a/doc/manual/cache/KeyPgOpNew.wakka b/doc/manual/cache/KeyPgOpNew.wakka index 4ce5079ecd..a0910ef747 100644 --- a/doc/manual/cache/KeyPgOpNew.wakka +++ b/doc/manual/cache/KeyPgOpNew.wakka @@ -17,7 +17,7 @@ Operator to dynamically allocate memory and construct data of a specified type. Exact number of elements to allocate. {{fbdoc item="ret"}} - A pointer of type [[DataType|datatype]] to the newly allocated data. + A pointer of type [[DataType|datatype]] to the newly allocated data, or null pointer if the memory allocation failed. {{fbdoc item="desc"}} The ##**New Expression**## operator dynamically allocates memory and constructs a specified data type. @@ -32,6 +32,10 @@ Operator to dynamically allocate memory and construct data of a specified type. Specifying an initial value of ##[[KeyPgAny|Any]]##, as in ##**New** //datatype//[//count//] {**Any**}## will allocate memory for the array, but not initialize the data. This is only valid on data types that do not have constructors (otherwise for data types with constructors, syntax of simple memory allocation with pointer conversion, like //Cptr(datatype Ptr, Allocate(count * Sizeof(datatype)))//, can be substituted to the invalid use of New...Any). + The total memory, in bytes, to be allocated with ##**New** //datatype//[//count//]## expression is calculated as ##//sizeof(datatype) * count//##, plus ##//sizeof(uinteger)//## if there is an implicit or explicit ##[[KeyPgDestructor|Destructor]]##. The total memory requested in bytes to be allocated must not overflow the value that can be held by a ##[[KeyPgUinteger|Uinteger]]##. The extra ##//uinteger//##, if allocated, stores the number of elements as part of the allocation, so that ##[[KeyPgOpDelete|Delete Statement]]## can determine the count of destructors to call. + + If the memory allocation fails, a null pointer is returned and no constructors are called. + The dynamic memory allocation process part provided by the ##**New Expression**## operator can be overloaded for user-defined types as a member operator ##[[KeyPgOpNewOverload|New Overload]]##. The following process part for data construction can never be modified. **Note:** Using ##//pointer// = **New** //datatype//[//count//]## may be unsafe if ##//pointer//## was declared with a type different from ##//datatype//## (for sub-type polymorphism purpose for example), because the pointer arithmetic fails to access the elements if the pointer type size is different from the size of ##//datatype//## (when using ##{{fbdoc item="keyword" value="KeyPgOpPtrIndex|Operator [] (Pointer index)"}}## or adding an offset (element number) to the pointer, or even when ##**Delete[] Statement**## itself (the array-version of ##[[KeyPgOpDelete|Delete Statement]]##) must destroy the elements). diff --git a/doc/manual/cache/KeyPgTypeTemp.wakka b/doc/manual/cache/KeyPgTypeTemp.wakka index 8466e10cee..eeb6b13af1 100644 --- a/doc/manual/cache/KeyPgTypeTemp.wakka +++ b/doc/manual/cache/KeyPgTypeTemp.wakka @@ -28,6 +28,8 @@ Creates a temporary copy of a user defined type It can also be used as an even shorter shortcut than ##[[KeyPgWith|With]]## (see below) if you are changing all the data-fields (or the n firsts only). + A temporary object is destroyed at the end of execution of the statement (where it's defined), but its corresponding allocated memory is not released and remains available (unused) until going out the scope where statement is. + Note: ##[[KeyPgStatic|Static]]## qualifier used at procedure definition level does not apply to temporary types. {{fbdoc item="ex"}} diff --git a/doc/manual/cache/KeyPgUnion.wakka b/doc/manual/cache/KeyPgUnion.wakka index e96b12ac15..dee92229bc 100644 --- a/doc/manual/cache/KeyPgUnion.wakka +++ b/doc/manual/cache/KeyPgUnion.wakka @@ -19,8 +19,8 @@ Declares a union user defined type. {{fbdoc item="desc"}} Unions are similar to a ##[[KeyPgType|Type]]## structure, except that the elements of a union occupy the same space in memory. Like Type, Union can use the optional ##[[KeyPgField|Field]] = //number//## specifier and supports also inheritance through the use of the [[KeyPgExtends|Extends]] keyword. - Unlike Type, Union can not contain variable-length strings, and more generally fields (or can not have bases) with constructors or destructors. Therefore, Union does not support to inherit from the ##[[KeyPgObject|Object]]## built-in type. - The size of the Union is the size of the largest data item. A data item can be an unnamed ##[[KeyPgType|Type]]##. Since they occupy the same space, only a single element can be used. + Unlike Type, Union can not contain variable-length strings and arrays, and more generally fields (or can not have bases) with constructors or destructors. Therefore, Union does not support to inherit from the ##[[KeyPgObject|Object]]## built-in type. + The size of the Union is the size of the largest data item. A data item can be an unnamed ##[[KeyPgType|Type]]##. Since they occupy the same space, only one element can usually be used at a given time. Unions support member functions including ##[[KeyPgConstructor|Constructor]]##, ##[[KeyPgDestructor|Destructor]]##, ##[[KeyPgMemberFunction|Function]]##, ##[[KeyPgOperator|Operator]]##, ##[[KeyPgProperty|Property]]## and ##[[KeyPgMemberSub|Sub]]##. All members of a union are public and access control is not supported. @@ -34,68 +34,132 @@ Declares a union user defined type. {{fbdoc item="ex"}} {{fbdoc item="filename" value="examples/manual/udt/union.bas"}}%%(freebasic) -' Example 1: bitfields. -type unitType - union - dim attributeMask as uinteger - type ' 32-bit uintegers can support up to 32 attributes. - isMilitary : 1 as uinteger - isMerchant : 1 as uinteger - end type - end union -end type - -dim myunit as unitType -myunit.isMilitary = 1 -myunit.isMerchant = 1 -print myunit.isMilitary ' Result: 1. -print myunit.isMerchant ' Result: 1. -print myunit.attributeMask ' Result: 3. +' Example 0: Little-endianness +' For larger integer values (as the following Ulong data type), +' bytes are arranged in memory in 'little-endian' byte order +' (the least significant byte gets stored first). + +Union UDU + ul As Ulong ' 32-bit data type + Type + ub0 As Ubyte ' 8-bit data type + ub1 As Ubyte ' 8-bit data type + ub2 As Ubyte ' 8-bit data type + ub3 As Ubyte ' 8-bit data type + End Type +End Union + +Dim As UDU u +u.ul = &h12345678 +Print Hex(u.ul) ' Result: 12345678 +Print Hex(u.ub3), Hex(u.ub2), Hex(u.ub1), Hex(u.ub0) ' Result: 12 34 56 78 + +Sleep +%% +{{fbdoc item="filename" value="examples/manual/udt/union1.bas"}}%%(freebasic) +' Example 1: Only one union member can be relevantly accessed at a time +Union member + username As String * 32 + posts As Ulong +End Union + +Dim As member userX +userX.username = "Samantha" +userX.posts = 1234 + +Print userX.username ' value of username corrupted because final value assigned to posts occupies same memory location +' ' (and this is reason that value of posts is displayed well) +Print userX.posts +Print + +Dim As member userY +userY.posts = 4321 +userY.username = "Alexander" + +Print userY.username +Print userY.posts ' value of posts corrupted because final value assigned to username occupies same memory location +' ' (and this is reason that value of username is displayed well) +Print + +Sleep +%% +{{fbdoc item="filename" value="examples/manual/udt/union2.bas"}}%%(freebasic) +' Example 2: Alternative to RGBA keyword and allowing to retrieve elementary colors values +UNION BGRA_UNION + colour AS ULONG + TYPE + blue AS UBYTE + green AS UBYTE + red AS UBYTE + alpha AS UBYTE + END TYPE +END UNION + +DIM ubgra AS BGRA_UNION + +' Setting the individual color values... +ubgra.red = &h33 +ubgra.green = &hcc +ubgra.blue = &h66 +' We can get a ULONG value +print HEX(ubgra.colour) ' Result: 33CC66 +print + +' Setting a ULONG value... +ubgra.colour = &h228844 +' We can get the individual color values +print HEX(ubgra.red) ' Result: 22 +print HEX(ubgra.green) ' Result: 88 +print HEX(ubgra.blue) ' Result: 44 +print + sleep +%% +{{fbdoc item="filename" value="examples/manual/udt/union3.bas"}}%%(freebasic) +' Example 3. +' Define a simple union. +Union AUnion + a As UByte + b As UInteger +End Union +' Define a composite type with an unnamed union. +Type CompType + s As String * 20 + ui As UByte 'Flag to tell us what to use in union. + Union + au As UByte + bu As UInteger + End Union +End Type + +' Flags to let us know what to use in union, +' because it's relevant to only use a single element of a union at a given time. +Const IsInteger = 1 +Const IsUByte = 2 -' Example 2. -' Define our union. -union AUnion - a as ubyte - b as integer -end union -' Define a composite type. -type CompType - s as string * 20 - ui as byte 'Flag to tell us what to use in union. - union - au as ubyte - bu as integer - end union -end type - -' Flags to let us know what to use in union. -' You can only use a single element of a union. -const IsInteger = 1 -const IsUByte = 2 - -dim MyUnion as AUnion -dim MyComposite as CompType - -' Can only set one value in union. +Dim MyUnion As AUnion +Dim MyComposite As CompType + +' Only one field within the union is set, without choice criterion. MyUnion.a = 128 MyComposite.s = "Type + Union" MyComposite.ui = IsInteger ' Tells us this is an integer union. -MyComposite.bu = 1500 +MyComposite.bu = 1500 ' Field set according to the above flag. -print "Union: ";MyUnion.a +Print "Simple Union: ";MyUnion.a -print "Composite: "; -if MyComposite.ui = IsInteger then - print MyComposite.bu -elseif MyComposite.ui = IsUByte then - print MyComposite.au -else - print "Unknown type." -end if +Print MyComposite.s & ": "; +If MyComposite.ui = IsInteger Then + Print MyComposite.bu +ElseIf MyComposite.ui = IsUByte Then + Print MyComposite.au +Else + Print "Unknown Type." +End If +Print -sleep +Sleep %% {{fbdoc item="lang"}} diff --git a/examples/manual/defines/fbgui.bas b/examples/manual/defines/fbgui.bas new file mode 100644 index 0000000000..8b2dc1f784 --- /dev/null +++ b/examples/manual/defines/fbgui.bas @@ -0,0 +1,13 @@ +'' examples/manual/defines/fbgui.bas +'' +'' NOTICE: This file is part of the FreeBASIC Compiler package and can't +'' be included in other distributions without authorization. +'' +'' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgDdfbgui +'' -------- + +#if __FB_GUI__ <> 0 + #print Executable subsystem: gui +#else + #print Executable subsystem: console +#endif diff --git a/examples/manual/udt/newoverload0.bas b/examples/manual/udt/newoverload0.bas new file mode 100644 index 0000000000..38e2b8849d --- /dev/null +++ b/examples/manual/udt/newoverload0.bas @@ -0,0 +1,57 @@ +'' examples/manual/udt/newoverload0.bas +'' +'' NOTICE: This file is part of the FreeBASIC Compiler package and can't +'' be included in other distributions without authorization. +'' +'' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgOpNewOverload +'' -------- + +Type UDTdisplayer + '' user UDT fields: + Dim As Byte b(1 To 1024*1024) + '' display fields: + Public: + Declare Operator New (ByVal size As UInteger) As Any Ptr + Declare Operator Delete (ByVal buf As Any Ptr) + Declare Operator New[] (ByVal size As UInteger) As Any Ptr + Declare Operator Delete[] (ByVal buf As Any Ptr) + Private: + Declare Static Function allocation (ByRef N As String, ByVal size As UInteger) As Any Ptr + Declare Static Sub deallocation (ByRef D As String, ByVal p As Any Ptr) +End Type + +Operator UDTdisplayer.New (ByVal size As UInteger) As Any Ptr + Return UDTdisplayer.allocation("New", size) +End Operator + +Operator UDTdisplayer.Delete (ByVal buf As Any Ptr) + UDTdisplayer.deallocation("Delete", buf) +End Operator + +Operator UDTdisplayer.New[] (ByVal size As UInteger) As Any Ptr + Return UDTdisplayer.allocation("New[]", size) +End Operator + +Operator UDTdisplayer.Delete[] (ByVal buf As Any Ptr) + UDTdisplayer.deallocation("Delete[]", buf) +End Operator + +Function UDTdisplayer.allocation (ByRef N As String, ByVal size As UInteger) As Any Ptr + Dim As Any Ptr p = Allocate(size) + Print "memory allocation for " & size & " bytes from '" & N & "' at address: " & p + Return p +End Function + +Sub UDTdisplayer.deallocation (ByRef D As String, ByVal p As Any Ptr) + Print "memory deallocation from '" & D & "' at address " & p + Deallocate p +End Sub + + +Randomize +Dim As UDTdisplayer Ptr pu1 = New UDTdisplayer +Dim As UDTdisplayer Ptr pu2 = New UDTdisplayer[3] +Delete pu1 +Delete[] pu2 + +Sleep diff --git a/examples/manual/udt/union.bas b/examples/manual/udt/union.bas index ac1b900391..d8dac6379e 100644 --- a/examples/manual/udt/union.bas +++ b/examples/manual/udt/union.bas @@ -6,65 +6,24 @@ '' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgUnion '' -------- -' Example 1: bitfields. -Type unitType - Union - Dim attributeMask As UInteger - Type ' 32-bit uintegers can support up to 32 attributes. - isMilitary : 1 As UInteger - isMerchant : 1 As UInteger - End Type - End Union -End Type - -Dim myunit As unitType -myunit.isMilitary = 1 -myunit.isMerchant = 1 -Print myunit.isMilitary ' Result: 1. -Print myunit.isMerchant ' Result: 1. -Print myunit.attributeMask ' Result: 3. -Sleep - -' Example 2. -' Define our union. -Union AUnion - a As UByte - b As Integer +' Example 0: Little-endianness +' For larger integer values (as the following Ulong data type), +' bytes are arranged in memory in 'little-endian' byte order +' (the least significant byte gets stored first). + +Union UDU + ul As ULong ' 32-bit data type + Type + ub0 As UByte ' 8-bit data type + ub1 As UByte ' 8-bit data type + ub2 As UByte ' 8-bit data type + ub3 As UByte ' 8-bit data type + End Type End Union -' Define a composite type. -Type CompType - s As String * 20 - ui As Byte 'Flag to tell us what to use in union. - Union - au As UByte - bu As Integer - End Union -End Type - -' Flags to let us know what to use in union. -' You can only use a single element of a union. -Const IsInteger = 1 -Const IsUByte = 2 - -Dim MyUnion As AUnion -Dim MyComposite As CompType - -' Can only set one value in union. -MyUnion.a = 128 - -MyComposite.s = "Type + Union" -MyComposite.ui = IsInteger ' Tells us this is an integer union. -MyComposite.bu = 1500 - -Print "Union: ";MyUnion.a -Print "Composite: "; -If MyComposite.ui = IsInteger Then - Print MyComposite.bu -ElseIf MyComposite.ui = IsUByte Then - Print MyComposite.au -Else - Print "Unknown type." -End If +Dim As UDU u +u.ul = &h12345678 +Print Hex(u.ul) ' Result: 12345678 +Print Hex(u.ub3), Hex(u.ub2), Hex(u.ub1), Hex(u.ub0) ' Result: 12 34 56 78 Sleep diff --git a/examples/manual/udt/union1.bas b/examples/manual/udt/union1.bas new file mode 100644 index 0000000000..72de8e649f --- /dev/null +++ b/examples/manual/udt/union1.bas @@ -0,0 +1,33 @@ +'' examples/manual/udt/union1.bas +'' +'' NOTICE: This file is part of the FreeBASIC Compiler package and can't +'' be included in other distributions without authorization. +'' +'' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgUnion +'' -------- + +' Example 1: Only one union member can be relevantly accessed at a time +Union member + username As String * 32 + posts As ULong +End Union + +Dim As member userX +userX.username = "Samantha" +userX.posts = 1234 + +Print userX.username ' value of username corrupted because final value assigned to posts occupies same memory location +' ' (and this is reason that value of posts is displayed well) +Print userX.posts +Print + +Dim As member userY +userY.posts = 4321 +userY.username = "Alexander" + +Print userY.username +Print userY.posts ' value of posts corrupted because final value assigned to username occupies same memory location +' ' (and this is reason that value of username is displayed well) +Print + +Sleep diff --git a/examples/manual/udt/union2.bas b/examples/manual/udt/union2.bas new file mode 100644 index 0000000000..b336caed8b --- /dev/null +++ b/examples/manual/udt/union2.bas @@ -0,0 +1,38 @@ +'' examples/manual/udt/union2.bas +'' +'' NOTICE: This file is part of the FreeBASIC Compiler package and can't +'' be included in other distributions without authorization. +'' +'' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgUnion +'' -------- + +' Example 2: Alternative to RGBA keyword and allowing to retrieve elementary colors values +Union BGRA_UNION + colour As ULong + Type + blue As UByte + green As UByte + red As UByte + Alpha As UByte + End Type +End Union + +Dim ubgra As BGRA_UNION + +' Setting the individual color values... +ubgra.red = &h33 +ubgra.green = &hcc +ubgra.blue = &h66 +' We can get a ULONG value +Print Hex(ubgra.colour) ' Result: 33CC66 +Print + +' Setting a ULONG value... +ubgra.colour = &h228844 +' We can get the individual color values +Print Hex(ubgra.red) ' Result: 22 +Print Hex(ubgra.green) ' Result: 88 +Print Hex(ubgra.blue) ' Result: 44 +Print + +Sleep diff --git a/examples/manual/udt/union3.bas b/examples/manual/udt/union3.bas new file mode 100644 index 0000000000..2216cf9b14 --- /dev/null +++ b/examples/manual/udt/union3.bas @@ -0,0 +1,52 @@ +'' examples/manual/udt/union3.bas +'' +'' NOTICE: This file is part of the FreeBASIC Compiler package and can't +'' be included in other distributions without authorization. +'' +'' See Also: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgUnion +'' -------- + +' Example 3. +' Define a simple union. +Union AUnion + a As UByte + b As UInteger +End Union +' Define a composite type with an unnamed union. +Type CompType + s As String * 20 + ui As UByte 'Flag to tell us what to use in union. + Union + au As UByte + bu As UInteger + End Union +End Type + +' Flags to let us know what to use in union, +' because it's relevant to only use a single element of a union at a given time. +Const IsInteger = 1 +Const IsUByte = 2 + +Dim MyUnion As AUnion +Dim MyComposite As CompType + +' Only one field within the union is set, without choice criterion. +MyUnion.a = 128 + +MyComposite.s = "Type + Union" +MyComposite.ui = IsInteger ' Tells us this is an integer union. +MyComposite.bu = 1500 ' Field set according to the above flag. + +Print "Simple Union: ";MyUnion.a + +Print MyComposite.s & ": "; +If MyComposite.ui = IsInteger Then + Print MyComposite.bu +ElseIf MyComposite.ui = IsUByte Then + Print MyComposite.au +Else + Print "Unknown Type." +End If +Print + +Sleep