Description
I want to propose a way to query the compiler in order to get information on the context of the compilation, at call site. In particular, this is mostly used to get source filename, line, function name.
Classical uses of this feature are logging, asserts, scoped variables (instrumentation, debugging...) and probably others I can't think of.
In C and C++ this is done through the __FILE__
and __LINE__
macros which are expanded by the preprocessor.
In Rust, there are file!
and line!
macros.
D also makes use of __FILE__
and such, though I don't know if it's actually a preprocessor.
And so on.
At the moment, something similar could be achieved by capturing a stack trace and looking at debug info, but this would not be very efficient. It would also be easily disturbed by the optimizations performed.
Zig could provide a @sourceInfo
builtin function, returning an instance along the lines of
pub const SourceInfo = struct {
file: []const u8,
line: comptime_int,
column: comptime_int,
module: type,
function: type,
function_name: []const u8,
}
Example usage:
pub fn main() void {
log(@sourceInfo(), "something something");
}
Example output:
[21:18:04] in 'main' (main.zig:2) | something something
Now, this leaves a usability concern: the other languages cited as examples all provide a way to the library writer to make get this information from client code. This means they can provide a log(msg: string)
function or macro that transparently uses the source information.
In current Zig, the only way is to explicitly call @sourceInfo()
and pass it to the function expecting it.
One solution is to provide a @callerSourceInfo
to get the source information from the call site into the callee function. But it doesn't play nice with function pointers or extern functions.