I’ve been learning Zig for a while but still haven’t figured out the difference between Builtin Functions and regular functions. Official document introducing a Builtin Functions is “Builtin functions are provided by the compiler”, what’s this mean? Can someone explain this? Thanks a lot!
builtin functions are hardcoded in compiler code: https://github.com/ziglang/zig/blob/master/src/BuiltinFn.zig
But what are the benefits of this? I guess it is platform independent functions.
not an expert on this, but I guess that some functions are better implemented in compiler code, such as import, meta programming stuff(@field, @TypeOf, etc).
From a user standpoint builtin functions are globally available without imports.
The regular functions you create or import from the standard library are just zig code. Say you wanted to find the type of a variable how would you build that in zig without access to @TypeOf provided to you by the compiler? It wouldn’t be possible. Things like @intCast, @bitCast etc are needed so the compiler knows when/how to type cast. Operations (+, -, * etc) are also effectively builtin functions but with syntactic sugar so you can use them in ways you’d expect. For things that you could implement utilizing what’s already provided like @log or @cos there’s typically dedicated hardware instructions which are more optimal than what the compiler might generate from your code implementation.
At least this is my understanding of it, someone from the Zig team might be able to better answer
Generally speaking builtins implement things that would otherwise be impossible (or very inconvenient) to implement in userland, like @src
for example.
Like, getting the type of something (@TypeOf
), or casting a constant / variable / expression to another type (@floatFromInt
, @intFromEnum
) - you can’t write a Zig function that does that. Not without using these builtins anyway - but you’re just wrapping them in your code then.
Funny enough, math functions like @cos
, @sin
, @fabs
are also builtins. I don’t complain, I like having them at hand always, but still kinda strange
They’re LLVM intrinsics and allow for more optimal code generation
cos: LLVM Language Reference Manual — LLVM 18.0.0git documentation
sin: LLVM Language Reference Manual — LLVM 18.0.0git documentation
fabs: LLVM Language Reference Manual — LLVM 18.0.0git documentation
Oh, I’m completely clear now!