FreeBASIC In Depth

Key differences from QB64 in -lang fb: Integer is pointer-sized (32/64-bit); Sleep n takes milliseconds; functions declare return types (As Double) and use Return; procedures used before their definition need Declare; arrays and variables can be declared in…

33.1 Language dialects (-lang)

-lang fb (default) modern FreeBASIC: explicit declarations, no suffixes on variables, no GOSUB, OOP, namespaces -lang fblite

FreeBASIC features with QBasic-style leniency (implicit variables, suffixes, GOSUB) maximum QuickBASIC compatibility (16-bit INTEGER, DEF FN, line numbers) -lang deprecated compatibility with very old FreeBASIC versions

Key differences from QB64 in -lang fb: Integer is pointer-sized (32/64-bit); Sleep n takes milliseconds; functions declare return types (As Double) and use Return; procedures used before their definition need Declare; arrays and variables can be declared in any block (For i As Integer = 1 To 10); +=-style operators exist.

33.2 A modern FreeBASIC program

' hello_fb.bas — compile with: fbc hello_fb.bas
Declare Function Average(values() As Double) As Double

Dim scores(1 To 5) As Double = {88.5, 92, 79.5, 95, 84}
Print Using "Average: ###.##"; Average(scores())

Dim As String nm = "FreeBASIC"
Print nm & " has " & Len(nm) & " letters"     ' & converts numbers to text automatically

Function Average(values() As Double) As Double
    Dim As Double total = 0
    For i As Integer = LBound(values) To UBound(values)
        total += values(i)
    Next
    Return total / (UBound(values) - LBound(values) + 1)
End Function

33.3 Object-oriented programming with TYPE

Other OOP features: Operator overloading (Operator + (a As Vec2, b As Vec2) As Vec2), Let (assignment) and Cast operators, Is for run-time type checks (If *shapes(0) Is CircleShape Then), Protected members, static members.

#include "vbcompat.bi"                           ' provides Format()

Type Shape Extends Object                       ' Extends Object enables RTTI and virtual methods
    Declare Abstract Function Area() As Double
    Declare Virtual Function Describe() As String
    Declare Virtual Destructor()
End Type

Function Shape.Describe() As String
    Return "Shape with area " & Format(Area(), "0.00")
End Function

Destructor Shape()
End Destructor

Type CircleShape Extends Shape                  ' "Circle" is a graphics keyword, so pick another name
    Private:
        rad As Double
    Public:
        Declare Constructor(ByVal r As Double)
        Declare Function Area() As Double Override
        Declare Property Radius() As Double
        Declare Property Radius(ByVal value As Double)
End Type

Constructor CircleShape(ByVal r As Double)
    This.rad = r
End Constructor

Function CircleShape.Area() As Double
    Return 3.14159265358979 * rad * rad
End Function

Property CircleShape.Radius() As Double
    Return rad
End Property

Property CircleShape.Radius(ByVal value As Double)
    If value >= 0 Then rad = value
End Property

Type RectShape Extends Shape
    w As Double
    h As Dou
…

33.4 Pointers and dynamic memory

Dim x As Integer = 10
Dim p As Integer Ptr = @x          ' address-of
*p = 20                            ' dereference
Print x                            ' 20

Dim buf As Integer Ptr = Allocate(10 * SizeOf(Integer))
For i As Integer = 0 To 9
    buf[i] = i * i                 ' pointer indexing
Next
Print buf[9]
Deallocate buf

Type Node
    value As Integer
    nxt As Node Ptr
End Type
Dim head As Node Ptr = New Node
head->value = 1
head->nxt = New Node
head->nxt->value = 2
Delete head->nxt: Delete head

Function Twice(ByVal n As Integer) As Integer
    Return n * 2
End Function
Dim fp As Function(ByVal As Integer) As Integer = @Twice   ' function pointer
Print fp(21)

33.5 Namespaces, preprocessor, and includes

#include once "fbgfx.bi"
#define SQUARE(x) ((x) * (x))
#ifdef __FB_WIN32__
    Const OS_NAME = "Windows"
#else
    Const OS_NAME = "Unix-like"
#endif

Namespace Geometry
    Const PI = 3.14159265358979
    Function CircleArea(ByVal r As Double) As Double
        Return PI * SQUARE(r)
    End Function
End Namespace

Print Geometry.CircleArea(2), OS_NAME
Using FB                                   ' fbgfx.bi declares the FB namespace (key codes, etc.)

33.6 Inline assembly

Inline assembly uses Intel syntax and works on x86/x86-64 targets; it is rarely needed today (the GCC backend -gen gcc -O 2 optimizes well).

Function AddAsm(ByVal a As Long, ByVal b As Long) As Long
    Dim result As Long
    Asm
        mov eax, [a]
        add eax, [b]
        mov [result], eax
    End Asm
    Return result
End Function
Print AddAsm(40, 2)

33.7 Threads

Also available: CondCreate/CondWait/CondSignal (condition variables) and ThreadCall (start a thread calling a procedure with arguments).

Dim Shared counter As Long
Dim Shared mtx As Any Ptr

Sub Worker(ByVal userData As Any Ptr)
    For i As Integer = 1 To 100000
        MutexLock mtx
        counter += 1
        MutexUnlock mtx
    Next
End Sub

mtx = MutexCreate()
Dim t1 As Any Ptr = ThreadCreate(@Worker)
Dim t2 As Any Ptr = ThreadCreate(@Worker)
ThreadWait t1
ThreadWait t2
MutexDestroy mtx
Print "Counter:"; counter          ' 200000 — without the mutex, updates would be lost