I thought it would print “errdefer” but it didn’t
am I misunderstanding how errdefer works?
const std = @import("std");
fn compareRandom(rng: std.rand.Random, comp: i64) !i64 {
const Error = error{TestError};
var randomNum = rng.intRangeAtMost(i64, 1, 2);
if (randomNum < comp) {
return randomNum;
} else {
return Error.TestError;
}
}
fn returnError(rng: std.rand.Random) !i64 {
var num = try compareRandom(rng, 0);
errdefer std.log.info("errdefer", .{});
return num;
}
pub fn main() !void {
const rngSeed = @intCast(u64, std.time.timestamp());
const rng = std.rand.DefaultPrng.init(rngSeed).random();
_ = returnError(rng) catch |err| {
std.log.info("{s}", .{err});
};
}
❯ zig build run
info: error.TestError
1 Like
cnx
April 17, 2022, 3:49pm
2
I thought it would print “errdefer” but it didn’t
am I misunderstanding how errdefer works?
var num = try compareRandom(rng, 0);
errdefer std.log.info("errdefer", .{});
You need to errdefer before possible error return.
3 Likes
hmf
April 25, 2025, 7:59am
3
My apologies for reviving this, but as a newbie I have been staring at this answer for some time and still don’t get it. Isn’t that errdefer
already before the return
?
I have a similar test and have compared it to several examples and just cannot see the issue. Can anyone explain this in more detail?
TIA
No, the return is the try
on the line before the errdefer
.
Remember that try <expression>
is syntactic sugar for <expression> catch |e| return e
, so every try
expression is also a return
expression.
4 Likes
hmf
April 25, 2025, 8:30am
5
@neurocyte Thank you. Makes sense now.
Sze
April 25, 2025, 6:46pm
6
I read that more like “what is the point of the errdefer if there is only a return directly after it?”.
Considering there is no way to trigger an error after the errdefer
was executed it seems useless, because there is nothing to trigger it.
So shouldn’t the code be this instead:
fn returnError(rng: std.rand.Random) !i64 {
errdefer std.log.info("errdefer", .{});
return try compareRandom(rng, 0);
}
This raises an interesting question: shouldn’t a load-bearing errdefer
without any possible error-returning paths be a compile error? It’s unreachable code.
Load-bearing meaning it’s not errdefer comptime unreachable
or errdefer unreachable
.
4 Likes