Attributes

V has several attributes that modify the behavior of functions and structs.

An attribute is a compiler instruction specified inside [] right before a function/struct/enum declaration and applies only to the following declaration.

  1. // [flag] enables Enum types to be used as bitfields
  2. [flag]
  3. enum BitField {
  4. read
  5. write
  6. other
  7. }
  8. fn main() {
  9. assert 1 == int(BitField.read)
  10. assert 2 == int(BitField.write)
  11. mut bf := BitField.read
  12. assert bf.has(.read | .other) // test if *at least one* of the flags is set
  13. assert !bf.all(.read | .other) // test if *all* of the flags is set
  14. bf.set(.write | .other)
  15. assert bf.has(.read | .write | .other)
  16. assert bf.all(.read | .write | .other)
  17. bf.toggle(.other)
  18. assert bf == BitField.read | .write
  19. assert bf.all(.read | .write)
  20. assert !bf.has(.other)
  21. }

Struct field deprecations:

  1. // oksyntax
  2. module abc
  3. // Note that only *direct* accesses to Xyz.d in *other modules*, will produce deprecation notices/warnings:
  4. pub struct Xyz {
  5. pub mut:
  6. a int
  7. d int [deprecated: 'use Xyz.a instead'; deprecated_after: '2999-03-01'] // produce a notice, the deprecation date is in the far future
  8. }

Function/method deprecations:

  1. // Calling this function will result in a deprecation warning
  2. [deprecated]
  3. fn old_function() {
  4. }
  5. // It can also display a custom deprecation message
  6. [deprecated: 'use new_function() instead']
  7. fn legacy_function() {}
  8. // You can also specify a date, after which the function will be
  9. // considered deprecated. Before that date, calls to the function
  10. // will be compiler notices - you will see them, but the compilation
  11. // is not affected. After that date, calls will become warnings,
  12. // so ordinary compiling will still work, but compiling with -prod
  13. // will not (all warnings are treated like errors with -prod).
  14. // 6 months after the deprecation date, calls will be hard
  15. // compiler errors.
  16. [deprecated: 'use new_function2() instead']
  17. [deprecated_after: '2021-05-27']
  18. fn legacy_function2() {}
  1. // nofmt
  2. // This function's calls will be inlined.
  3. [inline]
  4. fn inlined_function() {
  5. }
  6. // This function's calls will NOT be inlined.
  7. [noinline]
  8. fn function() {
  9. }
  10. // This function will NOT return to its callers.
  11. // Such functions can be used at the end of or blocks,
  12. // just like exit/1 or panic/1. Such functions can not
  13. // have return types, and should end either in for{}, or
  14. // by calling other `[noreturn]` functions.
  15. [noreturn]
  16. fn forever() {
  17. for {}
  18. }
  19. // The following struct must be allocated on the heap. Therefore, it can only be used as a
  20. // reference (`&Window`) or inside another reference (`&OuterStruct{ Window{...} }`).
  21. // See section "Stack and Heap"
  22. [heap]
  23. struct Window {
  24. }
  25. // V will not generate this function and all its calls if the provided flag is false.
  26. // To use a flag, use `v -d flag`
  27. [if debug]
  28. fn foo() {
  29. }
  30. fn bar() {
  31. foo() // will not be called if `-d debug` is not passed
  32. }
  33. // The memory pointed to by the pointer arguments of this function will not be
  34. // freed by the garbage collector (if in use) before the function returns
  35. [keep_args_alive]
  36. fn C.my_external_function(voidptr, int, voidptr) int
  37. // Calls to following function must be in unsafe{} blocks.
  38. // Note that the code in the body of `risky_business()` will still be
  39. // checked, unless you also wrap it in `unsafe {}` blocks.
  40. // This is useful, when you want to have an `[unsafe]` function that
  41. // has checks before/after a certain unsafe operation, that will still
  42. // benefit from V's safety features.
  43. [unsafe]
  44. fn risky_business() {
  45. // code that will be checked, perhaps checking pre conditions
  46. unsafe {
  47. // code that *will not be* checked, like pointer arithmetic,
  48. // accessing union fields, calling other `[unsafe]` fns, etc...
  49. // Usually, it is a good idea to try minimizing code wrapped
  50. // in unsafe{} as much as possible.
  51. // See also [Memory-unsafe code](#memory-unsafe-code)
  52. }
  53. // code that will be checked, perhaps checking post conditions and/or
  54. // keeping invariants
  55. }
  56. // V's autofree engine will not take care of memory management in this function.
  57. // You will have the responsibility to free memory manually yourself in it.
  58. [manualfree]
  59. fn custom_allocations() {
  60. }
  61. // For C interop only, tells V that the following struct is defined with `typedef struct` in C
  62. [typedef]
  63. struct C.Foo {
  64. }
  65. // Used to add a custom calling convention to a function, available calling convention: stdcall, fastcall and cdecl.
  66. // This list aslo apply for type aliases (see below).
  67. [callconv: "stdcall"]
  68. fn C.DefWindowProc(hwnd int, msg int, lparam int, wparam int)
  69. // Used to add a custom calling convention to a function type aliases.
  70. [callconv: "fastcall"]
  71. type FastFn = fn (int) bool
  72. // Windows only:
  73. // If a default graphics library is imported (ex. gg, ui), then the graphical window takes
  74. // priority and no console window is created, effectively disabling println() statements.
  75. // Use to explicitly create console window. Valid before main() only.
  76. [console]
  77. fn main() {
  78. }