FreeBasic Basics
Last modified October 18, 2026
In this article we cover the basic programming concepts of FreeBasic. The
examples use the default dialect, which is selected with -lang fb.
We start with a small console program and then introduce variables, control
flow, arrays, and procedures. For installation instructions, see the
FreeBasic introduction.
Compiling a program
Save each complete example in its own .bas file. The compiler
creates a native executable; compiling and running are separate steps.
Commands beginning with $ below are shell commands, not FreeBasic
statements. The examples use a Linux shell; on Windows, run the resulting
.exe file instead of ./program.
Print "Hello, FreeBasic!"
Print writes to the console and normally ends the line. Executable
statements at module level form the program's starting code; we do not need
to define a Main function. Newlines normally separate statements.
Indentation improves readability but does not define blocks: keywords such as
End If and End Function close them explicitly.
$ fbc -lang fb hello.bas $ ./hello Hello, FreeBasic!
Identifiers
Identifiers are names given to variables, procedures, types, and other
program entities. They consist of letters, digits, and underscores, and they
cannot begin with a digit. Identifiers are not case sensitive: userName
and USERNAME refer to the same variable.
Some words are reserved by the language. Reserved words such as
name, line, data, input,
and ptr cannot be used as identifiers.
Dim userName As String = "Lucy" USERNAME = "Mark" Print userName
The assignment through USERNAME changes the variable declared as
userName. Writing Dim USERNAME As String instead would
declare the same name twice and produce a duplicate-definition error. Use
consistent spelling even though the compiler ignores case.
$ fbc -lang fb identifiers.bas $ ./identifiers Mark
Comments
Comments are ignored by the compiler. A single-line comment starts with an
apostrophe. A multi-line comment is enclosed in /' and
'/.
' This is a single-line comment Print "Hello" ' trailing comment /' This is a multi-line comment '/ Print "Done"
The apostrophe can begin a whole comment line or follow executable code. The
two-line block between /' and '/ is also a comment;
only the two Print statements execute.
$ fbc -lang fb comments.bas $ ./comments Hello Done
Variables
A variable stores a value under a name. Variables are declared with the
Dim statement, and the data type follows the keyword
As. A variable can be initialized when it is declared.
Dim i As Integer = 1 Dim w As Double = 12.5 Dim s As String = "FreeBASIC" Dim b As Boolean = True Print "Count: "; i Print "Price: "; w Print "Language: "; s Print "Enabled: "; b
The variables hold an integer, a floating-point number, a string, and a
Boolean value. The semicolon in Print joins the values without
adding spaces, and a non-negative number is printed with a leading space.
A Boolean value prints as true or false.
Integer holds whole numbers and is target-sized: 32 bits on
32-bit targets and 64 bits on 64-bit targets. Long is always
32 bits, and LongInt is 64 bits. Double represents
floating-point values, which can have rounding error. String
stores text, while Boolean stores a truth value. A variable keeps
its declared type when a new value is assigned to it.
$ fbc -lang fb variables.bas $ ./variables Count: 1 Price: 12.5 Language: FreeBASIC Enabled: true
Operators
The operators +, -, and * perform
addition, subtraction, and multiplication. The / operator
performs floating-point division; \ performs integer division.
Mod gives the remainder. Parentheses group expressions explicitly.
Dim a As Integer = 15 Dim b As Integer = 4 Print "Division: "; a / b Print "Integer division: "; a \ b Print "Remainder: "; a Mod b
Although both operands are integers, 15 / 4 gives
3.75. Integer division gives 3, and the remainder
is 3. Assignment uses =; in a condition, the same
symbol tests equality. Inequality is written <>, not
!=.
$ fbc -lang fb operators.bas $ ./operators Division: 3.75 Integer division: 3 Remainder: 3
Type inference
The Var keyword declares a variable whose type is taken from the
initial value. The initializer is required.
Var age = 34 Var fullName = "John Doe" Print fullName; " is "; age; " years old"
The type of age is Integer and the type of
fullName is String, both inferred from the initial
values. This is compile-time inference, not dynamic typing. An unsuffixed
floating-point literal such as 3.14 infers Double.
$ fbc -lang fb inference.bas $ ./inference John Doe is 34 years old
Constants
Constants are declared with the Const keyword. Their value is
fixed at compile time and cannot be changed during the execution of the
program.
Const PI As Double = 3.14159265 Const MAX_RETRIES = 3 Print PI; MAX_RETRIES
PI has an explicit type; MAX_RETRIES takes its type
from the integer initializer. Uppercase constant names are a convention, not
a language requirement. Trying to assign a different value to either constant
is a compile-time error.
$ fbc -lang fb constants.bas $ ./constants 3.14159265 3
User input
The Input statement prints a prompt and reads a value from the
keyboard into a variable. The value is converted to the type of the variable.
Dim userName As String Input "Enter your name: ", userName Print "Hello "; userName
The declaration reserves a string variable, and Input stores the
entered text in it. The comma after the prompt suppresses the automatic
question mark; a semicolon would append ? . The transcript
includes the user's typed response. For a complete line containing commas,
use Line Input instead. Numeric Input is not a strict
validator: non-numeric text can convert to zero, so applications should validate
user input separately.
$ fbc -lang fb userinput.bas $ ./userinput Enter your name: Robert Hello Robert
Conditionals
The If statement executes a block of statements depending on a
condition. The ElseIf and Else branches are optional.
Dim num As Integer = -3
If num > 0 Then
Print "The number is positive"
ElseIf num = 0 Then
Print "The number is zero"
Else
Print "The number is negative"
End If
The first condition tests whether num is greater than zero. If
not, ElseIf tests equality with zero; Else handles
the remaining negative values. Exactly one branch runs. Change the initial
value to 0 or 3 to try the other branches.
$ fbc -lang fb conditionals.bas $ ./conditionals The number is negative
Select Case
The Select Case statement chooses a branch by comparing one
expression with several possible values.
Dim day As Integer = 3
Select Case day
Case 1
Print "Monday"
Case 2, 3
Print "Tuesday or Wednesday"
Case Else
Print "Other"
End Select
Several values can be listed in one Case separated by commas.
FreeBasic does not fall through to the next case: only the first matching
branch is executed.
Here day is 3, so Case 2, 3 matches.
Case Else is the optional fallback when no earlier case matches.
$ fbc -lang fb switch.bas $ ./switch Tuesday or Wednesday
For loop
The For statement repeats a block for a range of values. The
loop counter is incremented by one unless a Step is given.
Dim sum As Integer = 0
For i As Integer = 0 To 9
sum += i
Next
Print sum
The sum of the values 0 to 9 is 45. The loop variable is declared in the
For statement and is local to the loop.
Both endpoints are included, so there are ten iterations. The statement
sum += i means sum = sum + i. Next
advances the counter; Step 2 would advance it by two, and a
negative step can count downward.
$ fbc -lang fb forloop.bas $ ./forloop 45
While loop
The While loop repeats a block as long as the condition is true.
The condition is checked before each iteration, so the body may run zero times.
The block is terminated with Wend.
Dim i As Integer = 0
While i < 5
Print i
i += 1
Wend
The counter starts at zero and is printed before it is incremented. Once it
reaches five, the condition is false and the loop ends. Omitting
i += 1 would make this loop run indefinitely. Use
Exit While for an early exit and Continue While to
skip the rest of the current iteration.
$ fbc -lang fb whileloop.bas $ ./whileloop 0 1 2 3 4
Arrays
An array stores several values of the same type under one name. The bounds
are given in the declaration; UBound returns the upper bound.
Dim primes(0 To 4) As Integer = {2, 3, 5, 7, 11}
Dim i As Integer
For i = LBound(primes) To UBound(primes)
Print primes(i);
Next
Print
The trailing semicolon in Print primes(i); keeps the output on
one line. The final Print ends the line.
The bounds 0 To 4 allocate five elements, not four; an index
selects one element with parentheses, as in primes(i).
LBound and UBound let the loop follow the declared
bounds instead of assuming that every array starts at zero.
$ fbc -lang fb arrays.bas $ ./arrays 2 3 5 7 11
Functions
A function takes parameters, computes a value, and returns it with the
Return statement. The return type follows As after the
parameter list.
Function Add(a As Integer, b As Integer) As Integer
Return a + b
End Function
Dim x As Integer = 4
Dim y As Integer = 5
Dim z As Integer = Add(x, y)
Print "Output: "; z
Add declares two integer parameters and an integer result.
Add(x, y) passes the values four and five to those parameters.
Return a + b ends the call and supplies the result, which is
stored in z. In the fb dialect these numeric
parameters default to ByVal: changing them would not change
x or y. Write ByRef explicitly when a
procedure must modify the caller's variable.
$ fbc -lang fb functions.bas $ ./functions Output: 9
Subroutines
A Sub performs an action but returns no value.
Sub SayHello(ByVal personName As String)
Print "Hello, "; personName; "!"
End Sub
SayHello("Robert")
The argument "Robert" supplies the value of
personName. The subroutine prints the greeting and returns to
the statement after the call. Unlike Add, it cannot be used as a
value in an assignment. ByVal explicitly passes the string by
value; without a passing-mode qualifier, String parameters default
to ByRef in this dialect. Exit Sub can end a call early.
$ fbc -lang fb sub.bas $ ./sub Hello, Robert!
User-defined types
A Type groups several fields under one name. Fields are accessed
with the dot operator.
Type Person
personName As String
age As Integer
End Type
Function Greet(p As Person) As String
Return "Hello, " & p.personName & " (" & Str(p.age) & ")"
End Function
Dim people(0 To 1) As Person
people(0).personName = "Anna" : people(0).age = 31
people(1).personName = "Bob" : people(1).age = 45
For i As Integer = 0 To 1
Print Greet(people(i))
Next
Person defines a record with a string field and an integer field.
The people array contains two such records. A colon separates two
statements on one line; for example, the first pair of assignments initializes
Anna's two fields. Unlike a numeric parameter, a user-defined-type parameter
such as p As Person defaults to ByRef.
Greet reads the fields and returns a string. The
& operator concatenates strings, while Str(p.age)
converts the age to text. This avoids the extra numeric-printing space seen
in earlier examples. The loop calls the function once for each record and
prints the returned greeting.
$ fbc -lang fb full.bas $ ./full Hello, Anna (31) Hello, Bob (45)
These examples introduce the core syntax. The individual tutorials on declarations, reference parameters, and dynamic arrays explain those topics in more detail.
Source
Author
List all FreeBasic Tutorials.