Attributes
Attribute in Gofra is an keyword that is applied to object (function, variable, type)
Function attributes
pub
Applies to: functions
Mark function as exposed to other modules, and exposed inside compiled object file as function symbol for later linking
Example for module system:
// mod.gof:
pub func f[]
end
// When importing module with this function, it allows to call and use that function in any way:
import mod;
call mod.f
Example for object file linkage:
pub func f[]
end
// When compiling down to object file,
// symbol `f` remains public, and you can link that object file with other objects that externs `f` at linkage
naked
Applies to: functions
Naked functions does not have prologue and epilogue in machine code nor any compiled inserted code, they contains only assembly instructions.
They allows to write functions which will be broken due to compiler inserted code
For example:
naked func void f[]
// no prologue
inline_raw_asm "{machine_instructions}"
inline_raw_asm "ret"
// no epilogue
end
Notice: as compiler cannot insert boilerplate instructions into these functions, you must comply with return logic (link-registers) and manage arguments by own, naked functions supports parameters but it is only for type checking and calling convention only
extern
Applies to: functions
Mark function as defined somewhere else and not in produced artifact (object file, executable), for later linking with library/object file.
Those functions cannot have any body/operators inside it.
For example external function puts from libc library is declared as:
extern func int _puts[*char[]]
Compiler will try its best to perform such call assuming Gofra/C call convention / ABI
inline
Applies to: functions
Functions that marked as inline has no real call, it unwraps its body directly from direct call (inside caller)
Compiler tries to apply these attributes to inlineable functions via heuristics while inline optimizations are enabled
For example:
func int f[]
32 return
end
// On non inline call:
f return // yields 32
// If there is `inline` attribute
32 return // yields 32, expanded from inline function
Read more about optimizations...
no_return
Applies to: functions
Mark function as having no possible way out, for example exit system function, these function must has no return value
Compiler will warn you if you have function that always calls to no_return functions
Attribute allows to emit general compiler warnings and errors and perform possible optimizations,
mostly used in compiler library, but useful if you calling exit function and has nothing more
This checks ran only at compile-time and has no effect on runtime
no_return func void x[]
// Must has no way out
end
func void x1[]
call exit // warning, always calling to `no_return` function - propagate attribute
2 2 + drop // warning, unreachable code, and allows to apply optimizations like DCE
end
func void x1[]
false if ==
call exit // may have conditional `no_return` calls without any warning
end
end
Structure attributes
reorder
Applies to: structures
Apply reordering to structure. Reordering is a process when for performance reasons, fields of structure being re-ordered to solve alignment issues (redundant padding on structure memory layout)
By default, structures does not apply reordering, overridde by specifying this attribute.
Compiler will warn you if you have possible reordering on any structure
struct bad_layout
a char // 1 byte
b int // 8 byte
c char // 1 byte
end // Unpacked, 24 bytes
struct reorder reordered_layout
a char // 1 byte
b int // 8 byte
c char // 1 byte
end // Unpacked, reordered 16 bytes
// Order was transformed into [b, a, c] (int, char, char) re-using padding from int to char
packed
Applies to: structures
Apply packing to structure. Packing is a process when compiler removes all padding between fields of structure, laying them out contiguously in memory without any alignment.
By default, structures are padded to satisfy alignment requirements of their fields. Override by specifying this attribute.
Compiler will warn you if you have possible packing on any structure
struct unpacked_layout
a char // 1 byte
b int // 8 byte, aligned to 8 bytes -> 7 bytes padding before
c char // 1 byte
end // Padded, 24 bytes
struct packed packed_layout
a char // 1 byte
b int // 8 byte, no padding before
c char // 1 byte
end // Packed, 10 bytes
// Layout is [a, b, c] with no padding between fields