Skip to content

Default & Deleted Functions

Default Functions

In Helix, a default function is a function that is automatically provided by the compiler if no user-defined implementation is provided. These functions are typically used for common operations such as copying, moving, or assigning objects. Default functions can be explicitly declared using the default keyword in the function signature. Here’s an example of a default function that copies an object:

In helix copying, moving, or assigning follows the same syyntax and rules as C++.

struct Point {
x: i32
y: i32
fn Point(self, other: Point) -> Point = default // Copy constructor
fn op = (self, other: Point) -> Point = default // Copy assignment operator
fn Point(self, other: *Point) = default // Move constructor
fn op = (self, other: *Point) = default // Move assignment operator
fn op delete (self) = default // Destructor
// you can also have the const version of the functions
fn Point(const self, const other: Point) -> Point = default // Copy constructor
fn op = (const self, const other: Point) -> Point = default // Copy assignment operator
fn Point(const self, const other: *Point) = default // Move constructor
fn op = (const self, const other: *Point) = default // Move assignment operator
fn op delete (const self) = default // Destructor
}

Helix does by default generate the following functions if they are not defined by the user:

  • Copy Constructor
  • Copy Assignment Operator
  • Move Constructor
  • Move Assignment Operator
  • Destructor

If a destructor is defined by the user, the compiler will only generate:

  • Copy Constructor
  • Copy Assignment Operator

If a copy constructor or copy assignment operator is defined by the user, the compiler will generate:

  • Destructor

If a move constructor or move assignment operator is defined by the user, the compiler will generate:

  • Copy Constructor
  • Copy Assignment Operator

if the object contains a member that does not have a default move or copy constructor/assignment operator, the compiler will disallow the use of default functions for that object. same applies to members that are references or static members. You can also explicitly delete a function using the delete keyword in the function signature. This prevents the function from being used, and any attempt to call it will result in a compile-time error. Here’s an example of a deleted function:

struct NonCopyable {
data: i32
fn NonCopyable(self, other: NonCopyable) = delete // Delete copy constructor
fn op = (self, other: NonCopyable) = delete // Delete copy assignment
fn NonCopyable(self, other: *NonCopyable) = default // Move constructor
fn op = (self, other: *NonCopyable) = default // Move assignment
fn op delete (self) = default // Destructor
}
var a = NonCopyable(10)
var b = a // This will result in a compile-time error because the copy constructor is deleted
var c = std::move(a) // This is allowed because the move constructor is defined

Default and deleted functions are useful for controlling the behavior of objects in Helix, especially when dealing with resource management and ownership semantics. By using these features, you can ensure that your objects behave correctly and efficiently in various scenarios. Any function that is marked as default or delete must be defined inside a class or struct. and may not have the following modifiers:

  • static
  • const
  • eval
  • ffi "..."