-
-
Notifications
You must be signed in to change notification settings - Fork 613
Attributes and Directives
Oskar Nordquist edited this page Aug 21, 2020
·
12 revisions
-
@(link_name = <string>)
This attribute can be attached to variable and procedure declarations inside aforeign
block. This specifies what the variable/proc is called in the library.
Example;
foreign foo {
@(link_name = "bar")
testbar :: proc(baz : int) ---;
}
-
@(link_prefix = <string>)
This attribute can be attached to aforeign
block to specify a prefix to all names. So if functions are prefixed withltb_
in the library is you can attach this and not specify that on the procedure on the odin side. Example;
@(link_prefix = "ltb_")
foreign foo {
testbar :: proc(baz : int) ---; // This now refers to ltb_testbar
}
-
@export or @(export=true/false)
-
@(default_calling_convention = <string>)
This attribute can be attached to aforeign
block to specify the default calling convention for all procedures in the block. Example;
@(default_calling_convention = "std")
foreign kernel32 {
@(link_name="LoadLibraryA") load_library_a :: proc(c_str: ^u8) -> Hmodule ---;
}
- @(deferred_in=<proc>)
- @(deferred_out=<proc>)
- @(deferred_in_out=<proc>)
-
@(deferred_none=<proc>)
These attributes can be attached to a procedureX
which will be called at the end of the calling scope forX
s caller.
deferred_in
will receive the same parameters as the called proc.deferred_out
will receive the result of the called proc.deferred_in_out
will receive both.deferred_none
will receive no parameters.
baz :: proc() {
fmt.println("In baz");
}
@(deferred_none=baz)
bar :: proc() {
fmt.println("In bar");
}
foo :: proc() {
fmt.println("Entered foo");
bar();
fmt.println("Leaving foo");
}
// Prints:
// Entered foo
// In bar
// Leaving foo
// In baz
-
@(static)
Can be applied to a variable to have it keep its' state even when going out of scope. Same as a static local variable in C.
test :: proc() -> int {
@static foo := 0;
foo += 1;
return foo;
}
main :: proc() {
fmt.println(test()); // prints 1
fmt.println(test()); // prints 2
fmt.println(test()); // prints 3
}
-
@(thread_local)
Can be applied to a variable at file scope
@(thread_local) foo: int;
-
@(private)
Prevents a top level element from being exported with the package. In Odin elements beginning with '_' will not be exported. This attribute allows you to explicitly prevent something from being exported without naming it with an '_'.
package foo
_this_is_private :: 0;
this_is_not :: 1;
@private
this_is_also_private :: 2;
-
@(deprecated=<string>)
Mark a procedure as deprecated. Runningodin build/run/check
will print out the message for each usage of the deprecated proc.
@(deprecated="'foo' deprecated, use 'bar' instead")
foo :: proc() {
...
}
-
@(builtin)
Marks builtin procs in Odin's "core:runtime" package. Cannot be used in user code.
-
#packed
This tag can be applied to struct. By doing so, the Odin compiler will omit padding and preserve the order of fields in a struct. -
#raw_union
This tag can be applied to a struct. Struct's fields will share the same memory space which serves the same functionality asunion
s in C language. Useful when writing bindings especially. -
#align
This tag can be applied to a struct or union. This tag in form#align N
specifies the struct's alignment to N bytes.
Foo :: struct #align 4 {
b: bool,
}
Bar :: union #align 4 {
i32,
u8,
}
-
#no_nil
This tag can be applied to a union to not allow nil values.
A :: union {int, bool};
B :: union #no_nil {int, bool};
Possible states of A:
{} // nil
{int}
{bool}
Possible states of B:
{int} // default state
{bool}
-
#complete
This tag can be applied to a switch on anenum
to ensure allcase
s are covered. Notably, it requires allcase
s to be tested individually, default case does not count.
Foo :: enum {
A,
B,
C,
}
test :: proc() {
bar := Foo.A;
// Ok
#complete switch bar {
case Foo.A:
case Foo.B:
case Foo.C:
}
// Error
#complete switch bar {
case Foo.A:
case Foo.B:
case:
}
}
-
#no_alias
This tag can be applied to a procedure parameter that is a pointer. This is a hint to the compiler that this parameter will not alias other parameters. This is equivalent to C's
__restrict
.
foo :: proc(#no_alias a, b: ^int) {}
-
#caller_location
This tag is used as a function's parameter value. In the following function signature,
alloc :: inline proc(size: int, alignment: int = DEFAULT_ALIGNMENT, loc := #caller_location) -> rawptr
loc
is a variable of type Source_Code_Location
(see core/runtime/core.odin
) that is automatically filled with the location of the line of code calling the function (in this case, the line of code calling alloc
).
-
#c_varag
Used to interface with vararg functions in foreign procedures.
foreign foo {
bar :: proc(n: int, #c_vararg args: ..any) ---;
}
-
#require_results
Ensures procedure return values are acknowledged.
foo :: proc() -> bool #require_results {
return true;
}
main :: proc() {
foo(); // won't compile
_ = foo(); // Ok
}
-
#type
This tag doesn't serve a functional purpose in the compiler, this is for telling someone reading the code that the expression is a type. The main case is for showing that a procedure signature without a body is a type and not just missing its body, for example:
foo :: #type proc(foo : string);
bar :: struct {
gin : foo;
}
- #bounds_check
-
#no_bounds_check
#bounds_check
and#no_bounds_check
are flags that control Odin's built-in bounds checking of arrays and slices. Any statement, block, or function with one of these flags will have their bounds checking turned on or off, depending on the flag provided. Valid uses of these flags include:
proc_without_bounds_check :: proc() #no_bounds_check {
#bounds_check {
#no_bounds_check fmt.println(os.args[1]);
}
}
-
#assert
Assert ran at compile time. -
#defined
Checks if an identifier is defined.
n: int;
when #defined(n) { fmt.println("true"); }
if #defined(int) { fmt.println("true"); }
when #defined(nonexistent_proc) == false { fmt.println("proc was not defined"); }
-
#file #line #procedure
Return the current file path, line number, or procedure name, respectively. Used like a constant value.
file_name :: #file;
-
#location
Returns aruntime.Source_Code_Location
(seecore/runtime/core.odin
). Can be called with no parameters for current location, or with a parameter for the location of the variable/proc declaration
foo :: proc() {};
main :: proc() {
n: int;
fmt.println(#location());
fmt.println(#location(foo));
fmt.println(#location(n));
-
#load
Returns a[]u8
of file contents at compile time
foo := #load("path/to/file");
bar := #load(#file);
fmt.println(string(foo));