<terinjokes>
bummer. i don't know enough zig to send a PR for that issue myself
_whitelogger has joined #zig
_whitelogger has joined #zig
cameris has quit [Quit: leaving]
curtisf has joined #zig
hio has quit [Quit: Connection closed for inactivity]
<terinjokes>
is it possible to call a c pointer function (eg, `[*c]extern fn()`)?
<terinjokes>
I can use @ptrCast, unsure if there's a better way
kristoff_it has joined #zig
cloudhop has quit [Quit: Page closed]
return0e has quit [Ping timeout: 248 seconds]
return0e has joined #zig
kristoff_it has quit [Ping timeout: 245 seconds]
husho has joined #zig
I_Right_I has quit [Remote host closed the connection]
hio has joined #zig
curtisf has quit [Quit: Page closed]
_whitelogger has joined #zig
_whitelogger has joined #zig
hio has quit [*.net *.split]
daurnimator[m] has quit [*.net *.split]
hoppetosse has quit [*.net *.split]
return0e has quit [*.net *.split]
THFKA4 has quit [*.net *.split]
ijneb has quit [*.net *.split]
return0e has joined #zig
hio has joined #zig
hoppetosse has joined #zig
daurnimator[m] has joined #zig
THFKA4 has joined #zig
ijneb has joined #zig
Summertime has quit [Quit: Sunsetting.]
Summertime has joined #zig
hio has quit [Ping timeout: 252 seconds]
hio has joined #zig
<gonz_>
https://pastebin.com/mVG5pZSN - Will this reliably reduce the size of the struct to whatever is inside of it? The output I get seems to indicate that were only getting the size of the u32.
<gonz_>
Also, has anyone figured out a way to create phantom types in zig? I don't really know enough about the way to handle comptime to create them.
<andrewrk>
marijnfs, it's because I want to rely on result location semantics (copy elision part 1) to re-do coroutines. and I want that coroutine rework for doing networking, just because I think it's really nice to have async/await syntax for networking operations. this enables writing "pipeline" style coding which I want for both self hosted compiler and package manager
<daurnimator>
andrewrk: I searched for deleted articles and found nothing
<andrewrk>
daurnimator, me too. I'm not sure what happened
<daurnimator>
andrewrk: the logo needs to be documented as under an acceptable copyright notice
<daurnimator>
wikipedia like cc-by-sa-4.0 or cc-by-4.0 or GFDL
<daurnimator>
andrewrk: where *is* the source of the logo? I see that it's an SVG. could you just throw it into a repository ziglang/logo on github?
<andrewrk>
my last name has an `e` between l and y
<daurnimator>
Also, I'm happy to have just submitted #2688; I've been working on it for a few days: breaking the rule of "don't implement your own crypto" :P
<scientes>
add the text of the license go github can automatically parse it
<scientes>
in LICENSE
porky11 has quit [Ping timeout: 248 seconds]
<andrewrk>
I gave up after 5 minutes looking for a plain test cc-by-sa 4.0 LICENSE file
<curtisf>
Is there a convenient way to use a tagged union with anonymous structs as the fields? Like, how could I easily make a literal of the type `Op = union(enum) { Assign: struct { d: V, s: V, } }` ?
<Tetralux>
Sahnvour: Ty (y)
<Tetralux>
(PS: IRC noob here)
<Sahnvour>
you're welcome
porky11 has quit [Ping timeout: 248 seconds]
porky11 has joined #zig
<Tetralux>
Well
<Tetralux>
I managed to build zig
<Tetralux>
And tested every fifth commit for a while, before and after 0.4.0, and then every tenth commit until I needed LLVM 7.
<Tetralux>
Every single commit does NOT have a stack trace on release-safe.
<Tetralux>
Stupid question but... did release-safe EVER have a stack trace?
<emekankurumeh[m]>
it should
<gamester>
Tetralux: I commented out the asserts in your code and then I get "attempt to unwrap null". Turns out it's index.? in append.
<gamester>
linux + master here
<gamester>
well master from sometime yesterday
<Tetralux>
So, it also commented out the assert for index != null and also got the attempt to unwrap null.
<Tetralux>
I also*
<Tetralux>
So I'm glad THAT is the same!
<gamester>
But only on --release-safe. Even if I insert an explicit if (index == null) { std.debug.warn, std.os.exit ...} then it only hits this branch on release-safe
<Tetralux>
Yeah - on debug or release-fast - everything goes just fine.
<Tetralux>
Well
<Tetralux>
master on release-fast is wrong
<Tetralux>
but doesn't crash
<Tetralux>
but master on debug mode is fine.
<Tetralux>
Also
<Tetralux>
gamester: Can you verify that if you remove the if (occupied) branch and check for if (!occupied) instead
<Tetralux>
gamester: that it also doesn't work.
kristoff_it has quit [Ping timeout: 246 seconds]
<gamester>
Tetralux: yeah I think so. Sorry I've been changing the code a bit, I'm in the flow. I've reduced the issue a lot. Also noticed some additional problems, maybe. does the allocator's create function guaranteed initialization? I don't know. But you don't initialize the buckets explicitly but that's not the source of the issue
very-mediocre has quit [Ping timeout: 256 seconds]
<marler8997_>
why does the example include -DCMAKE_PREFIX_PATH=$HOME/local in the LLVM example?
<marler8997_>
I would think you would only need that argument when building clang, so clang could find LLVM, but why does llvm include it?
<gamester>
Tetralux: So you'll noticed that in the paste that I sent you, if you fix the secureZero call, then both with and without --release-safe will work. If you remove the secureZero or leave it with the wrong slicing syntax, then with --release-safe you'll hit the null index problem
<gamester>
Tetralux: but through this issue didn't you find an issue with a crashing stack trace? It looked like that to me, running the program through gdb. That's a bug.
<curtisf>
Where are slice-literals allocated? On the stack? Where does their lifetime end? The end of the statement they're in? end of block? end of function?
<gamester>
a slice is just a struct with a pointer and a length, so the same as with any struct. It's placed wherever you place it. There's no hidden allocation.
<curtisf>
I mean if I write `x = f([]Obj{a(), b(), c()})` where is the array of 3 elements allocated? The expression doesn't say where it goes
<emekankurumeh[m]>
I'm pretty sure that would be a compile error
<curtisf>
hrm maybe this is only working because it's being evaluated at comptime
<emekankurumeh[m]>
that would be an array not a slice, so that would go in the stack
<emekankurumeh[m]>
nvm
<marijnfs>
man the vulkan triangle code crashes my window manager
<marijnfs>
that's some strong code
<gamester>
vulkan, vulkan, vulkan.... shame on you
<gamester>
that's vulkan for you
<andrewrk>
curtisf, that's an array literal. the new syntax is `[_]Obj{a(), b(), c()}`. if it is known at compile time, it is allocated in the static const data section of the object file
<andrewrk>
function call results are runtime known when not in a comptime context, so that will be a runtime-known array literal. those are allocated on the stack
<andrewrk>
in the result location branch that I'm working on merging soon, array literals are not allocated anywhere; instead they directly instantiate the result location
<andrewrk>
so if you were to, for example, do `some_pointer.* = [_]Obj{a(), b(), c()};` then the array literal would directly initialize some_pointer[0], some_pointer[1], and some_pointer[2]
<andrewrk>
in your example you are passing the array literal to a function foo() as the first argument. the result location for parameters is the stack
<curtisf>
ah, so I should be using `[_]`, didn't realize that. So how do I figure out how long slices/pointers to arrays remain valid? Is it always the end of the enclosing block? or can it be shortened because it will be emplaced somewhere with a shorter lifetime?
<andrewrk>
curtisf, when you update to the latest master, yes
<Sahnvour>
it's valid as long as the original data it is pointing to is
<andrewrk>
the lifetime of something is always determined by the `var` or `const` declaration
<emekankurumeh[m]>
are you going to do another round of PR after you merge the result location branch?
<andrewrk>
emekankurumeh[m], yes
<andrewrk>
at least one
<andrewrk>
for automatically allocated parameters, the lifetime ends when the callee returns
<andrewrk>
if you have an array you declared with `var` or `const` then it's the scope that the declaration is in
<andrewrk>
donpdonp, I didn't realize you had gotten so far on your mastodon client project
<curtisf>
OK. Thanks for explaining! I think what I'm doing is OK. For future learners I think it would be useful to have these rules written down somewhere in the manual with positive&negative examples
<andrewrk>
curtisf, certainly. in fact I plan to do even better than that: have debug & release-safe modes reliably detect violations and produce crashes with useful messages
<curtisf>
:)
karrick_ has joined #zig
karrick_ has quit [Remote host closed the connection]
<Tetralux>
gamester: Oh man ty!
<gamester>
np!
<Tetralux>
gamester: So basically, the probably was that undefined != zeroing.
<Tetralux>
That seems to be the lesson here.
<Tetralux>
Right?
<Tetralux>
Well - and a bug with release-safe stack traces.
jjido has joined #zig
<Tetralux>
If so - I was actually aware of that point of uncertainty as I was writing init, but figured it would be okay because I'd find out later if it was full of junk.
<Tetralux>
But then I found myself unable to debug it x'D
<Tetralux>
It seems very unwiedly to have to slice a unknown-length pointer to Self and then pass that to a zeroing function for just ensuring that your variable is zeroed, considering that's normally what you want.
<donpdonp>
andrewrk: hey thx! I made that page just yesterday. and thanks for Zig. :)
<gamester>
Tetralux: well I introduced the init function for the Bucket. You were just calling allocator.create without initializing the resulting contents of the pointer
<Tetralux>
Oh yeah
<Tetralux>
I remember
<andrewrk>
Tetralux, release-safe stack traces produces more complicated debug info, which zig's standard library isn't capable of understanding yet
<Tetralux>
I actually had an init for it when I wrote it originally, but removed it because again - I figured I'd just discover if it wasn't zeroed later.
<gamester>
Tetralux: well I don't remember the best way to zero things since I never need to. Usually you're more explicit than that. But I do think secureZero is how people do this.
<andrewrk>
but it's something that can be improved
<andrewrk>
secureZero is more to do with leaking sensitive data
<gamester>
ah, between the fields
<andrewrk>
Tetralux, for many types, such as structs, zig purposefully does not define a memory layout. this allows zig to put runtime safety check information in the spaces between fields
<andrewrk>
this is how we have safety for accessing the wrong union field, for example
<andrewrk>
if you were to memset a struct to zero you would mess up the safety information
<Tetralux>
andrewrk: Okay - so - couple of things:
<Tetralux>
andrewrk: RE debug info in release-safe: Ah, I see. I'm guessing then that using if (index == null) { ... } is better than assert(index != null) if you intend to use release-safe then.
<Tetralux>
At least until you have a stack trace for it.
<andrewrk>
assert(false); is defined to call the panic handler function in release-safe mode, and the default panic handler dumps a stack trace and then calls abort()
<Tetralux>
Okay, so until the stack trace, using if (index == null) assert(false) then.
<andrewrk>
it's better to use assert when assert is appropriate; the fact that stack traces lack debug info in release-safe mode is not really relevant in my opinion. you can override the default panic behavior if you don't like it
<Tetralux>
Define appropriate.
<Tetralux>
xD
<andrewrk>
assert is defined simply as: fn assert(ok: bool) { if (!ok) unreachable; }
<Tetralux>
Indeed it is.
<andrewrk>
assert is appropriate when the condition being false is unreachable code
<Tetralux>
I see.
<andrewrk>
note that errors such as parse errors or "file not found" errors are not unreachable code
<andrewrk>
they are in fact quite reachable
<gamester>
yeah you should use assert for index != null except that you actually don't need to since that's what index.? does
<andrewrk>
the less obvious it is that a code path is unreachable, the more helpful an assert will be
<Tetralux>
So, since I tend to use assert to mean "tell me if this isn't true", and assert(index != null) is probably "reachable", I shouldn't use it like that.
<Tetralux>
Okay
<Tetralux>
There's a thing here
<andrewrk>
if it's reachable, then you should handle the situation in some way. probably returning an error or reporting the situation to the user
<andrewrk>
or panicking. that's sometimes quite reasonable
<Tetralux>
In this case, index being null means the code is wrong.
<Tetralux>
And that I need to fix it.
<Tetralux>
Which is why I used assert.
<Tetralux>
But
<andrewrk>
gamester is correct though - if you were to do index.? that is a language-level assert that the index is not null
<Tetralux>
Indeed.
<Tetralux>
Makes sense.
<Tetralux>
But my problem was multi-faceted.
<Tetralux>
In this case.
<Tetralux>
My create'd struct wasn't zeroed.
<gamester>
yeah if the code is wrong when an assert would be untrue then using an assert is correct
<andrewrk>
agreed ^
<Tetralux>
Likewise.
<Tetralux>
It seems like a bit of a corner case to me, perhaps.
<Tetralux>
Because I was using it redundantly to index.?
<Tetralux>
And because my struct wasn't zeroed properly, it was quite hard for me to determine what was actually happening
<Tetralux>
because it didn't happen in a mode with a trace.
<Tetralux>
Though, doing var thing = create(); thing.* = init() will help avoid that.
<Tetralux>
I'm not used to there being copy elision like that :p
<Tetralux>
Well - that's maybe not quite right, but hopefully you get what I mean xD
<Tetralux>
Basically
gamester has quit [Remote host closed the connection]
gamester has joined #zig
<Tetralux>
When programming exploratively, use the pattern of thing.* = Thing.init() which should hopefully get you a trace when something does go wrong
<gamester>
marijnfs: the same thing happened to me. Hmmm
<Tetralux>
Asserts are NOT compiled out of release-fast right?
gamester has quit [Remote host closed the connection]
<Tetralux>
Apologises for babbling - thinking out loud. Don't mind me xD
<Tetralux>
Oh right - I remember why I removed Bucket.init now: I was having trouble figuring out how I set the array fields to all zeroes.
<Tetralux>
return Bucket{ .occupied = (an array of items all zeroes), ... }
<Tetralux>
Is the idiomatic way to do that, to use mem.zero?
<Tetralux>
(.occupied is [N]T)
<marijnfs>
gamester: yeah i'm trying to pinpoints where it is
porky11 has quit [Quit: Leaving]
<andrewrk>
Tetralux, you can create an array literal with all zeroes (or any pattern) like this: [1]i32{0} ** 100
Ichorio has joined #zig
<Sahnvour>
Tetralux: you can assign a default value to occupied in the struct declaration, something like `occupied: [N]T = [_]{ 0 } ** N,`
<Sahnvour>
andrew's syntax is more correct :p
<andrewrk>
Sahnvour, yours looks correct to me too, and that's a good point about default struct field value
<andrewrk>
oh, you forgot the T, I see it now :)
<curtisf>
cls
curtisf has quit [Quit: Page closed]
<Sahnvour>
yup
<Sahnvour>
which makes me think, is the `: [NT]` required in this case ?
<Tetralux>
Yep, I actually remembered I could do that just before I came back to read this. x'D
<Tetralux>
Is `[_]{0} ** N` real syntax?
<Tetralux>
Can you infer the eltype like that?
<Sahnvour>
if you add T, it is, otherwise it's not
<Sahnvour>
that's a typo on my side
<Tetralux>
You mean [T]{0} ** N?
<scientes>
[_] was added very recently
<Sahnvour>
[_]T{0}**N
<Sahnvour>
[_] means you let the compiler determine the size by the number of following elements in braces, iiuc
<Tetralux>
Okay - so on 0.4.0, it's an error to use that to mean "infer the count please"
<Tetralux>
Whereas on master it infers the count as you describe.
<Tetralux>
But you can just omit it in both places and it also works.
<Tetralux>
ie: .occupied = []T{0} ** N,
<Tetralux>
(coerces to a fixed array)
<Tetralux>
Also
<Tetralux>
I just realised
<Tetralux>
The data field isn't always integers right
<Tetralux>
because 0 isn't a T unless T is an integer.
<Tetralux>
And for the same reason I can't default-struct-field-value it either.
<Tetralux>
Right?
<Sahnvour>
oh, you want to zero-initialize any type ?
<Tetralux>
Well
<Tetralux>
I suppose I can get away with 'undefined' there because I only read it if occupied is true
<Tetralux>
But now you mention it
marijnfs_ has joined #zig
<Sahnvour>
undefined seems like the good tool to use in that case
<Tetralux>
Also FYI, I actually _have_ to use [_]bool{false}**N for default-struct-field-values.
<Tetralux>
Without it, it doesn't coerce to a fixed array, like it would if you are creating a struct literal.
<Tetralux>
That seems a little inconsistent.
<Tetralux>
andrewrk: You mentioned that you cannot zero a struct because it will fudge with the safety. Can you elaborate on how that safety works, and what would happen if you _do_ zero it?
<fengb>
Really weird thing: fd_t is the 4th reference so it seems to just disappear
<scientes>
Tetralux, default values will take care of that use case
<Tetralux>
scientes: It would, yeah. I do want to understand that though ;p
fengb has quit [Ping timeout: 256 seconds]
<Tetralux>
Hey - I just want to say thanks for all the help. It is most appreciated!
<Tetralux>
It helped quite a lot :p
<scientes>
Tetralux, welcome!
<Tetralux>
o7
gamester has joined #zig
<gamester>
marijnfs: The issue seems to be in the .imageFormat or .imageColorSpace fields of VkSwapchainCreateInfoKHR
<gamester>
I'm really surprised that the validation layers aren't detecting this
<gamester>
I ported over my instance create logic to make sure I had working validation layers and they didn't complain, though I've yet to test them to make sure they're on
<gamester>
well nvm, they are sending me informational messages so obv they're on
<marijnfs>
gamester: yeah are all layers on actually?
<marijnfs>
there are many
<marijnfs>
so whats the fix?
<gamester>
I'm not sure yet
<gamester>
Don't know what the issue is
<Tetralux>
gamester: Thanks for the help and your effort earlier! I appreciate it.
<gamester>
no problem
<Tetralux>
o7
<marijnfs>
gamester: nice catch though, seems strange that any swapchain creation shouldnt be able to do that
<marijnfs>
could be driver bug
<gamester>
invalid enum value
<gamester>
hmm but the format choosing logic is identical to mine
<marijnfs>
gamester: i was printing availableFormats in chooseSwapSurfaceFormat, and it crashes in the fmt function
<marijnfs>
maybe some memory is screwed up
<gamester>
yeah
<marijnfs>
gamester: when i run it in valgrind it goes crazy
<marijnfs>
but actually i get a triangle!
<gamester>
hah
<marijnfs>
lots of writes in not alloced memory..
<gamester>
wow how did I forget about valgrind
cyanmide has joined #zig
<gamester>
marijnfs: details.deinit() shouldn't be there
<marijnfs>
createCommandBuffers (main.zig:189)
<gamester>
in querySwapChainSupport
<gamester>
I think that's the issue. One wrongly placed 'free' is enough to get Vulkan to crash the OS' display manager! YES! PROGRESS!
<marijnfs>
gamester: that actually fixes it, you da man
<gamester>
andrew: ^
<gamester>
andrewrk
<gamester>
marijnfs: maybe you can do a pull request to vulkan triangle stuff? I don't know git
<gamester>
just remember to free that struct elsewhere, and maybe this should be designed differently so this is less likely to happen
<marijnfs>
gamester: sure i will
<marijnfs>
gamester: you would almost want a defer to pass through a return, or attach it to the runtime lifetime of a variable
<gamester>
Also the validation layers should 100% detect this, right? I'm going to sleep but this has to be fixed by them as well.
<gamester>
maybe it is detected but the logic still goes through and we can't see the message cause the OS partly crashes
<gamester>
maybe there is file logging
<marijnfs>
gamester: yeah, anyway i created the pull request
jjido has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<marijnfs>
it would be nice to have a lifetimedefer
<andrewrk>
marijnfs, that's a destructor
<andrewrk>
thanks for the PR
gamester has quit [Remote host closed the connection]
gamester has joined #zig
<gamester>
ok I redirected stderr and indeed the issue is caught
<gamester>
I should have done that from the start heh
<marijnfs>
andrewrk: does zig have that?
<andrewrk>
no
<andrewrk>
you can just make one though. make a function to call when the variable's lifetime is ending, and then call it
<andrewrk>
the bug here probably originated from porting c++ code (which does have destructors) to zig, and I made a mistake
<marijnfs>
andrewrk: yeah, it would be nice if zig could pick up such mistakes
<gamester>
not possible
<gamester>
valgrind can!
<andrewrk>
even the planned safety features would not have been able to catch this problem, since the type is extern and thus has a well-defined memory layout
<marijnfs>
andrewrk: yeah it's a hard problem
<andrewrk>
interacting with C APIs always has unsafety problems. that's true in rust as well, all this vulkan code would have `unsafe` keywords everywhere
<andrewrk>
this is an area where zig can actually help a bit more than rust, since the seam between safe and unsafe is less rigid
<marijnfs>
the proper debug support is really nice in zig
<marijnfs>
does clangs memory sanitizer pick such things up?
<andrewrk>
it was an invalid free you said? actually in this case the debug allocator I've been working on would have been able to catch it
<marijnfs>
andrewrk: yeah was wondering aobut that
<andrewrk>
we can test that claim
<marijnfs>
is it finally finished:P
<gamester>
the free wasn't invalid
<gamester>
it was too early
<marijnfs>
yeah its not a doubble free
<andrewrk>
ah. so passing bogus pointer to vulkan
<marijnfs>
yes, not even passing, just the info struct that is returned (and not to be used by vulkan) is already freed
<marijnfs>
so it might just have some crazy values
<gamester>
nah, it's the arrays in the struct that get freed
<gamester>
so yes a bogus pointer
<andrewrk>
I'm not sure about memory sanitizer. there is an open issue to investigate what integrating with that would look like
<andrewrk>
there's also an issue about making stack allocations detect safety issues