返回资讯中心
外部精选
软件工程
#开发者实时流

Partial Operator Precedence (Zig Devlog)

error: contradictory hash for package with fingerprint 0x7118c1b07efea3d0 and version 0.0.0: libogg-0.0.0+1.3.7-0KP-flwMAACKAIH-iEs4gbg30ll_FQ-cW50JvLZO8VTg

Hacker News 最新ErenayDev2026/10/25 · 11 天前22 分钟阅读

以下正文同步自 Hacker News 最新,版权归原站所有,已转换为易读排版。

andy@bark ~/d/ffmpeg (main)> zig build error: contradictory hash for package with fingerprint 0x7118c1b07efea3d0 and version 0.0.0: libogg-0.0.0+1.3.7-0KP-flwMAACKAIH-iEs4gbg30ll_FQ-cW50JvLZO8VTg error: contradictory hash for package with fingerprint 0x7118c1b07efea3d0 and version 0.0.0: libogg-0.0.0+1.3.7-0KP-foYNAAAaj0YJOwRQs7kTN-ivzRMYTjtKzr6Apelj info: potential cause: package ownership dispute info: potential cause: maintainer neglected to bump version after making changes info: potential cause: dependency on unreleased changes info: hint: use --print-tree to visualize all package versions and hashes

October 13, 2026 Printing Package Tree

There is a new --print-tree CLI option to zig build, that looks like this:

andy@bark ~/d/groovebasin (main)> zig build --print-tree ffmpeg ffmpeg-8.1.1-5-zT7QA_AkUgTOx4ZqOUVZsHSk9iv97BInIiubIM6ifr67 ├─ libz zlib-1.3.1-1-ZZQ7ldENAAA7qJjUXP6E6xnRuV-jDL9dyoJFc_eb3zQ6 │ └─ zlib N-V-__8AAB0eQwD-0MdOEBmz7intriBReIsIDNlukNVoNu6o ├─ mbedtls mbedtls-3.6.4-E4NUR2wWAAAUSvVbho9aaU31-e4D8glu9l1VfxKezBkV (not fetched) ├─ openssl openssl-3.3.2-TC9C3Ze3ZABaKR5hc8KRnRPhTClKrKQKqTnXTUYkvmSR (not fetched) ├─ libressl libressl-4.0.0--kqV4KPTAACsSRP8mSIZmqgVa5OZjw6WEgvcftWkLu-c (not fetched) ├─ libmp3lame libmp3lame-3.100.1-7-67wlF2CxEwDWlVOMMLBNPbnDi5kE2OmH0azUHU2Y4DZY ├─ libvorbis libvorbis-0.0.0+1.3.7-1wt9j_QPAADVure94TG4ecBMLD8eIAzWd6ZxVOmBBPCu │ ├─ libvorbis N-V-__8AAA7lSAA6p7eRmPGVeA9uHmeiJ2DX-ISiPliRJ8Y7 │ └─ libogg libogg-0.0.0+1.3.7-0KP-foYNAAAaj0YJOwRQs7kTN-ivzRMYTjtKzr6Apelj │ └─ libogg N-V-__8AAFM3CwD6iAA1kggMPR8NHZ8VTb2zvRZ1Mt4BUfq9 ├─ libogg libogg-0.0.0+1.3.7-0KP-foYNAAAaj0YJOwRQs7kTN-ivzRMYTjtKzr6Apelj │ └─ libogg N-V-__8AAFM3CwD6iAA1kggMPR8NHZ8VTb2zvRZ1Mt4BUfq9 └─ nasm nasm-3.0.1-B_NnpQpTAAA25UxvqONakXtmj-a78PGe3xfgyDFgetb0 ├─ nasm N-V-__8AAEAMKAFrNesgN6ZM9sxj37fq_i7UJe5nKkLmyRJI └─ zlib zlib-1.3.1-1-ZZQ7ldENAAA7qJjUXP6E6xnRuV-jDL9dyoJFc_eb3zQ6 └─ zlib N-V-__8AAB0eQwD-0MdOEBmz7intriBReIsIDNlukNVoNu6o pulseaudio pulseaudio-16.1.1-10-mk_62DNlNwCDcTJ5iGhTxeCoetuAFKE1FrYNw5AErtX- StaticHttpFileServer StaticHttpFileServer-1.0.0-j-0gwes2AAByCgpeLBNR2hOaGVsDz9u8I6o54ft10OxU └─ mime mime-4.0.0-zwmL--0gAACndOVlROQeDnM0chfojNDS8tpohlsBqMNy

If a terminal is detected, it prints in color, which is a bit easier to read.

This early exits before running configurer, so that problems causing configurer compilation errors can be troubleshooted.

Similarly, --configure is added, which is defined to “exit after the configuration phase” which is the exact behavior that --fetch used to do. --fetch is changed to “Fetch all dependencies including lazy ones; exit without configuration”.

zig build --help now works even when configuration fails, or when there is no build.zig file:

info: initialize build.zig template file with "zig init" info: see "zig --help" for more options error: no build.zig file found, in the current directory or any parent directories Usage: zig build [steps] [options]

Steps: (unavailable due to build.zig compilation failure) Project-Specific Options: (unavailable due to build.zig compilation failure)

System Integration Options: --search-prefix [path] Add a path to look for binaries, libraries, headers --sysroot [path] Set the system root directory (usually /) ... Available System Integrations: Enabled:

(unavailable due to build.zig compilation failure)

General Options: -h, --help Print this help to stdout and exit -l, --list-steps Print available steps to stdout and exit ...

August 27, 2026 Pointer Stability for ArrayLists

Author: Robbie Lyman

Pointer Stability Locks were added to std’s Hash Map containers in 2024. A pull request initially opened by Leo Emar-Kar in 2025 now brings this technique for ensuring memory safety to std.ArrayList.

To make use of this in your code, add a call to lockPointers() when you first store a pointer to an element or a slice of elements backed by the ArrayList, and call unlockPointers() when those pointers are no longer needed.

Here’s a somewhat contrived example. Let’s suppose we are managing two ArrayLists, say one of which is holding in memory the contents of some input, while the other is storing chunks of interest; maybe each line. Here’s a version of this process which has a bug; see if you can spot it.

const std = @import("std");

const Context = struct { history: std.ArrayList(u8), lines: std.ArrayList([]const u8),

fn parse(ctx: *Context, allocator: std.mem.Allocator, input: []const u8) !void { const slice = try ctx.history.addManyAsSlice(allocator, input.len); @memcpy(slice, input); var it = std.mem.tokenizeScalar(u8, slice, '\n'); while (it.next()) |line| { try ctx.lines.append(allocator, line); } } };

Did you spot the bug? The problem is that elements of Context.lines.items depend on the location of Context.history.items, but this location may change if Context.history needs to grow beyond its current capacity. Here’s a reproduction of the bug:

test "Context.parse" { const input = "I'm first!\n"; const input_two = \But this text \is juuuuuuuuuuuuuuuuuuuuuuuuust long enough that it \causes a problem! \And the problem could be that we segfault! \Which is no fun to run into. ; var ctx: Context = .{ .history = .empty, .lines = .empty, }; const gpa = std.testing.allocator; defer ctx.history.deinit(gpa); defer ctx.lines.deinit(gpa); try ctx.parse(gpa, input); try ctx.parse(gpa, input_two); try std.testing.expectEqualStrings("I'm first!", ctx.lines.items[0]); }

If I run this code with zig test, I get the following output (plus a little more).

====== expected this output: ========= I'm first!␃

======== instead found this: ========= UUUUUUUUUU␃

====================================== First difference occurs on line 1: expected: I'm first! ^ ('\x49') found: UUUUUUUUUU ^ ('\x55') 1/1 blah.test.Context.parse...FAIL (TestExpectedEqual)

Not great, right? This does tell us that we have a bug, but depending on your comfort debugging memory issues (and your choice of allocator, which will change how the bug manifests!), you might be lost for quite a while before you spot the fix.

Since we’ve stored pointers after the first call to parse in our test, what happens if we make this change?

try ctx.parse(gpa, input);

  • ctx.history.lockPointers();
  • defer ctx.history.unlockPointers(); try ctx.parse(gpa, input_two); try std.testing.expectEqualStrings("I'm first!", ctx.lines.items[0]);

We get a panic with a stack trace that shows us where our assumption about pointer stability was violated!

thread 3023222 panic: reached unreachable code /Users/robbie/bin/lib/std/debug.zig:442:14: 0x102d2506f in assert (test) if (!ok) unreachable; // assertion failure ^ /Users/robbie/bin/lib/std/debug.zig:1880:15: 0x102d31ef7 in assertUnlocked (test) assert(l.state == .unlocked); ^ /Users/robbie/bin/lib/std/array_list.zig:1348:50: 0x102e3ced7 in ensureTotalCapacityPrecise (test) self.pointer_stability.assertUnlocked(); ^ /Users/robbie/bin/lib/std/array_list.zig:1341:51: 0x102e3cdff in ensureTotalCapacity (test) return self.ensureTotalCapacityPrecise(gpa, growCapacity(new_capacity)); ^ /Users/robbie/bin/lib/std/array_list.zig:1237:41: 0x102e4e5c3 in resize (test) try self.ensureTotalCapacity(gpa, new_len); ^ /Users/robbie/bin/lib/std/array_list.zig:1461:28: 0x102e4e40f in addManyAsSlice (test) try self.resize(gpa, try addOrOom(self.items.len, n)); ^ /Users/robbie/src/advent-of-code/2024/blah.zig:8:51: 0x102e4dc1f in parse (test) const ptr = try ctx.history.addManyAsSlice(allocator, input.len); ^ /Users/robbie/src/advent-of-code/2024/blah.zig:35:18: 0x102e4e167 in test.Context.parse (test) try ctx.parse(gpa, input_two);

Nice, that’s already a big help: now I can see that I should consider memory safety issues as a probable cause of my test failure in addition or instead of a logic issue. Obviously this example was somewhat contrived, but I do find myself reaching for std.ArrayList as this type of backing storage in real code, so I hope you can see real-world use cases for it yourself.

Before I close, I want to point out something subtle: unlike HashMap and its friends, ArrayList is ordered, which means that operations on the list may move elements around even without moving, resizing or freeing the backing memory of the list as a whole. For example, the pointer (well, slice) returned by addManyAsSlice(gpa, n) may not point to the final n elements of the list if you call orderedRemove() or pop(). For this reason, although orderedRemove() and pop() never allocate, they will trigger the same assertion above after a call to lockPointers().

正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。

打开原文
去社区讨论 →