Skip to content

Odd behavior of undefined Optional value when passed through anyopaque pointer #23201

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
CodeingerCat opened this issue Mar 11, 2025 · 3 comments
Labels
question No questions on the issue tracker, please.

Comments

@CodeingerCat
Copy link

Zig Version

0.14.0

Steps to Reproduce and Observed Behavior

So, I was trying to use an optional field to keep track of whether a filed in a structure should be 'usable' by using a 'null' value to flag its 'un-usability', and I ran across this odd behavior. This behavior occurs when an Optional field in a structure is set to undefined, where depending on what optimization level that is used, it ends up with a different result when checking if the value is 'null' before and after being passed through an anyopaque pointer cast and back.

const std = @import("std");

pub const std_options = std.Options{
    .log_level = .info,
};

const TypeHolder = struct {
  value: ?u32,
};

pub fn main() !void {
  var a = TypeHolder{.value = undefined};
  const p_a = &a;
  std.log.info("Before: {*} {}", .{p_a, p_a.value == null});
  const p_b: *anyopaque = @ptrCast(p_a);
  const p_c: *TypeHolder = @ptrCast(@alignCast(p_b));
  std.log.info("After: {*} {}", .{p_c, p_c.value == null});
}

Debug
info: Before: main.TypeHolder@d148dffcb0 true
info: After: main.TypeHolder@d148dffcb0 true

ReleaseSafe
info: Before: main.TypeHolder@c1261ffbf8 false
info: After: main.TypeHolder@c1261ffbf8 true

ReleaseSmall
info: Before: main.TypeHolder@7c80fffea8 true
info: After: main.TypeHolder@7c80fffea8 true

ReleaseFast
info: Before: main.TypeHolder@dcea3ff900 false
info: After: main.TypeHolder@dcea3ff900 true

Expected Behavior

I was hoping it would set the value to not-null with an undefined value, but I'm not sure exactly what the correct behavior would be after a bit more thought.

This might be related to these 2 issues, but I'm not sure what the correct behavior is based on these either:

@CodeingerCat CodeingerCat added the bug Observed behavior contradicts documented or intended behavior label Mar 11, 2025
@CodeingerCat
Copy link
Author

If the target platform matters here, I was testing this on Windows.

@alexrp
Copy link
Member

alexrp commented Mar 11, 2025

Your code is invalid because it depends on the value of an undefined field. Please see the relevant language reference section: https://ziglang.org/documentation/master/#undefined

undefined is not an observable state as in e.g. JavaScript.

@alexrp alexrp closed this as not planned Won't fix, can't repro, duplicate, stale Mar 11, 2025
@alexrp alexrp added question No questions on the issue tracker, please. and removed bug Observed behavior contradicts documented or intended behavior labels Mar 11, 2025
@CodeingerCat
Copy link
Author

Sorry for the clutter. I confused myself with this one and have now realized I probably meant to do TypeHolder{.value = @as(u32, undefined)} instead. For some reason, I thought setting the filed to undefined would set it as a not null undefeind value instead of 'nullness' and value both being undefined.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question No questions on the issue tracker, please.
Projects
None yet
Development

No branches or pull requests

2 participants