diff options
| author | 2026-10-14 10:47:30 +0000 | |
|---|---|---|
| committer | 2026-10-14 10:47:30 +0000 | |
| commit | 4a22cf28742bf33577678de494aa09ab60a3c820 (patch) | |
| tree | d9133c7ab431fd3f41ef7713a869d23be4539244 /docs/LEARN.md | |
| parent | Merge four small fixes: std hovers, capture terminator, bare static calls, vo... (diff) | |
| parent | zc: add the defer statement (diff) | |
Merge the defer statement; todo: tick it, add its follow-ups
Diffstat (limited to 'docs/LEARN.md')
| -rw-r--r-- | docs/LEARN.md | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/docs/LEARN.md b/docs/LEARN.md index a3588e7..d514d85 100644 --- a/docs/LEARN.md +++ b/docs/LEARN.md @@ -174,6 +174,44 @@ output: 0 5 6 ``` +### defer + +`defer expr;` or `defer { statements }` runs code when the enclosing block ends: after the last statement, and also on `return`, `break` and `continue` out of it. defers in a block run last registered first. the deferred code is compiled at each exit, so it sees the variables as they are when it runs, and `return e;` computes `e` before any defer runs. `defer rt.free(p);` hands the owner `p` over at that point: `p` stays usable until the block ends and is not freed twice. `return`, `break` and `continue` are not allowed inside a deferred statement. + +[example source](../examples/learn/34-defer.zc): + +```zc +namespace; +include rt; +fn say(n) { rt.put_n(n); rt.put_c(32); return 0; } +int work(int n) { + int* p = rt.new(int); + defer rt.free(p); + defer say(100); + *p = n * 2; + say(*p); + if (n > 2) return *p + 1; + say(1); + return 0; +} +fn main() { + for (let i = 0; i < 4; i++) { + defer { say(i); rt.put_c(10); } + if (i == 1) continue; + say(work(i)); + } +} +``` + +output: + +```text +0 1 100 0 0 +1 +4 1 100 0 2 +6 100 7 3 +``` + ## numbers and strings ### sized integers |
