jevinskie has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
fengb has quit [Ping timeout: 256 seconds]
jevinskie has joined #zig
curtisf has quit [Quit: Page closed]
<marler8997_>
getting a pointer from a windows function callback, but zig won't let me ptrCast it "cast increases pointer alignment"...any suggestions?
Marumoto has quit [Quit: Page closed]
<marler8997_>
looks like @intToPtr(*Foo, @ptrToInt(ptr)) works, but I'm sure there's a better way
tdl7rt has joined #zig
<emekankurumeh[m]>
have you tried `@alignCast`?
st4ll1 has joined #zig
ltriant has quit [Ping timeout: 258 seconds]
<marler8997_>
looks like that just aligns a pointer
<marler8997_>
that's the callback signature, the 3rd parameter `DWORD_PTR dwInstance` is a pointer to a struct
<marler8997_>
so I need to cast it accordingly
<mikdusan1>
marler8997_: are you doing a 32-bit or 64-bit binary?
<marler8997_>
not sure actually
<marler8997_>
dumpbin tells me x64
<marler8997_>
FILE HEADER VALUES
<marler8997_>
8664 machine (x64)
<mikdusan1>
i'm curious at *u32, did a cimport do that automatically or was that hand-crafted?
<marler8997_>
hand-crafted
<marler8997_>
just matched the windows function definition
<marler8997_>
is there another pointer type I could use that would allow me to cast it to pointers with large align types?
<mikdusan1>
i think the issue is "u32". by default zig assumes you align at 4 bytes for that. if it were u64, then it would be 8 bytes. and that would match Foo which is 8 byte align.
<marler8997_>
it's gotta work on both platforms
<marler8997_>
the pointer is already aligned
<mikdusan1>
right. Foo would be 4-byte on 32-bit platforms.
<marler8997_>
but when I get the pointer back in the callback, zig doesn't know it's aligned
<marler8997_>
so how do you recommend I tell it to skip the alignment check
<mikdusan1>
for giggles change *u32 to *usize
<marler8997_>
you don't know how big Foo is
<marler8997_>
it may or may not have the same alignment as a uszie
<andrewrk>
marler8997, alignment errors more likely point to an actual bug rather than needing to cast
<marler8997_>
so `instance` is a just a "pass-through" pointer that gets passed to the function where I set the callback
<marler8997_>
and I get it back in the callback
<andrewrk>
whatever alignment it requires you should fulfill it. it's unlikely you need to do any casting fro that to happen
<marler8997_>
I do fullfull it
<marler8997_>
but once I get the pointer back inside the callback, the type information is gone
<marler8997_>
zig no longer knows where that pointer came from
<andrewrk>
these are user-data parameters? better to make them usize rather than *u32
<marler8997_>
yes, user-data parameters
<marler8997_>
It doesn't matter whether it's usize or u32
<marler8997_>
it's not a pointer to either one
<andrewrk>
so you'll necessarily do ptrToInt / intToPtr and that makes sense
<andrewrk>
I'm suggesting to change the extern fn prototype
<marler8997_>
ok, thought I'd check to make sure that was the right way to go
<marler8997_>
sure, but how does that help?
<marler8997_>
it's not a pointer to a u32 or a usize
<andrewrk>
it is a usize though that's exactly what it is
<marler8997_>
it's a pointer provided by the user
<marler8997_>
it could point to anything
<andrewrk>
it doesn't have to be a pointer
<marler8997_>
In my case it points to a struct
<marler8997_>
correct, it also doesn't have to be a pointer
<andrewrk>
it's a usize
<marler8997_>
so long as it fits in a usize
<marler8997_>
oh right
<marler8997_>
you're saying a usize, not *usize
<andrewrk>
right
<marler8997_>
yes that would work as well
<andrewrk>
and the @ptrToInt / @intToPtr that you'll have to is the simplest thing that makes sense in this case
<marler8997_>
maybe a better solution as it sort of signals to the developer that they really need to know what they are doing
<andrewrk>
and the @intToPtr does the align checks etc
<marler8997_>
cool, thanks for the tip
<marler8997_>
note that at some point I'll probably submit these windows functions to zig std library
<andrewrk>
sounds good
bgiannan has left #zig ["WeeChat 2.5"]
samtebbs has joined #zig
<tdl7rt>
andrewrk: any way to have absolute addresses for variables (like --defsym foo=0x40001000)?
st4ll1 has quit [Ping timeout: 245 seconds]
st4ll1 has joined #zig
wootehfoot has joined #zig
avoidr has quit [Quit: leaving]
tdl7rt has quit [Ping timeout: 256 seconds]
<gamester>
andrewrk: timerfd_create in os/linux.zig returns a usize. Is that correct? It does no error handling so I have to check for -1. In C it returns an int, in the kernel it seems to return a long.
<gamester>
okay I can copy what os.zig's epoll_create1 does
ace-_ has joined #zig
<ace-_>
now this may cut against the grain of the zig language, but im interested in knowing if its possible
<ace-_>
using comptime functions, is it possible to make type providers?
<ace-_>
in the sense the zig compiler at compile time, could read in a file and generate types, or make function calls to some server to generate types
<ace-_>
i would try it myself, ive followed zig a bit in the past, but today is the first day im giving it an actual try
<ace-_>
just sayin', it would blow my mind if the answer is yes
<ace-_>
make network* calls to some server.
<ace-_>
a mistype there
<ace-_>
I suppose not, the docs seem pretty clear on the matter:
<ace-_>
it infers the implicit schema of json given as samples to the compiler at compile time. either as const strings, read in from file, or over the network
<ace-_>
many, many other uses
<ace-_>
idris is the only other somewhat popular language that implements type providers as a first class citizen
<ace-_>
haskell and other languages can fake it by generating files before compile time and then just reading them in, its clunky but it works
<ace-_>
there are type providers for csv files, yaml files, sql servers (grabs the schema over the wire)
ace-_ has quit [Read error: Connection reset by peer]
ace-_ has joined #zig
<samtebbs>
ace-_: Yeah it doesn't look like something that you could do at compile time dynamically
<samtebbs>
But you could create some external tool that would parse the zig source and transform it before compiling, based on some external resource
<ace-_>
oh, i was just using the source file itself as a temporary placeholder. the input file would usually be something other than zig code
<ace-_>
ill take a look, thanks
<ace-_>
as i said, if this restriction is removed, this would be the most absolutely simple way imaginable to implement type providers
<ace-_>
but who knows? it might just be better to generate zig code from json
<ace-_>
json/csv/yaml/etc
<sammich>
with the external tool that would be sort of like how protobuf and similar things work no?
<samtebbs>
sammich: I didn't know what that was but have looked into it and I guess so
<samtebbs>
If it had a Zig backend then you could certainly use it
<ace-_>
well, from what i understand protoc has tools built in to generate files for popular languages. this would just actually be a lifting of a restriction in zig.
<ace-_>
the nice thing about the F# type providers, is that it works very well with intellisense and you never have to see the ugly files it generates
<ace-_>
i could imagine it working very similarly in zig, but maybe not
tdl7rt has joined #zig
<ace-_>
these types are generated at compiletime it plays very nicely with autocompletion and the only thing that is required to generate these complex types and parsers/serializers for those types are just a sampling of the data
<ace-_>
so you never have to look at the ugly complex types, serializers, and parsers it generates, its all done at compile time and exposed by the compiler to the ide
<ace-_>
and the only thing you would have to write (in a hypothetical future zig) would just look like `const TestMsg = JsonProvider("{ 'id' : 1, 'name' : }")
<ace-_>
and that would generate the type definition for the TestMsg struct, and the serializer/parser combo to go to and from json
<ace-_>
i think you can do something very similar to this right now in zig
<ace-_>
but however, you cannot read files or open up a socket to some api server to do the same thing
<ace-_>
so instead of the direct sample in the previous example, you can have a csv provider infer the schema of a csv file and then generate the appropriate struct for the rows and the parser/serializer
<ace-_>
would look something like: `const TestCsv = CsvProvider("./some.csv", "\t")` and in this example, its a tab separated file
<ace-_>
now, this may be a little too magical for some people. but zig's comptime system would make this stuff soooo easy to implement
<ace-_>
and in practice it tends to work quite well, especially in exploratory stages
<ace-_>
and since its all done at compile time, its all type safe and (for the most part) zero overhead compared to hand writing
<tgschultz>
you can read files at compile time using @embedFile
<tgschultz>
you are correct though that you can't connect to a server
<sammich>
@embedFile is a nice feature. its a pretty painful experience to do the same in go
<andrewrk>
tdl7rt, yes, make it a global and use @intToPtr
<andrewrk>
gamester, std.os should gain timerfd API which will do the error checking as well as abstract libc/no libc
<tralamazza>
andrewrk: (tdl7rt was temp nick) but then it becomes a pointer no?
<andrewrk>
what's the difference?
<tralamazza>
just the .*. everywhere
<tralamazza>
it should be called the Zig emoji
<andrewrk>
there is another way. you can put the variable in its own section and then in the linker script put that section at whatever address you want
<tralamazza>
yah that's what i meant by section trickery ;)
<tralamazza>
it's fine, just asking because some compilers have that feature
<andrewrk>
I personally would do the pointer thing
<andrewrk>
it's an old issue so take whatever I wrote there skeptically
<andrewrk>
this issue is on my mind but I won't have a formal proposal until closer to 1.0
<mmx87>
Ah, I see, thanks. I think the editions in Rust were a quite good idea and the "versioned" approach to managing multiple versions of a language is quite a good idea to keep the language modern without breaking backwards compatibility.
jevinskie has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
samtebbs has quit [Remote host closed the connection]
marijnfs_ has joined #zig
<andrewrk>
one difference is that I think rust is still open to adding new features to the language (correct me if I'm wrong) but I do envision Zig being "done" at some point
<andrewrk>
of course there will still be work to do such as keeping up with LLVM versions and adding new targets and intrinsics
<tralamazza>
how do you usually debug zig? gdb?
<andrewrk>
yes
<tralamazza>
is lldb a thing?
<andrewrk>
yes
<andrewrk>
and msvc
<andrewrk>
I use lldb on macos, msvc on windows
<tralamazza>
can you have zig expressions inside the debugger?
<andrewrk>
you can have c expressions, which are nearly the same
wootehfoot has quit [Quit: Leaving]
<andrewrk>
I filed a request to have zig added to gdb but nobody has acted on it yet
<andrewrk>
we need to harass them more
<tralamazza>
i'm using gdb, but if lldb allows me to have zig in it (and it works ofc), i'd switch
<andrewrk>
this is a feature request of lldb/gdb. unlikely to happen until zig becomes much more mainstream
<andrewrk>
c expressions in the debugger are quite close to zig expressions though. gdb/lldb don't care about the difference between . and -> for example
<andrewrk>
gonna close IRC and make more progress on copy elision branch
<companion_cube>
is the syntax already more or less 1.0 in your mind?
<scientes>
companion_cube, parts have stabilized IMHO
<scientes>
but not all of it
<mmx87>
Yeah, I think they're quite open to adding new features. For it to work to be "done" Zig would need to be reasonably flexible to be wrapped for the future. Can that even be realistically done? Let's take async, coroutines or closures as an example. It was quite late when languages implemented it because they saw the value in them at some point and
<mmx87>
only after they were "battle-tested" out by new programming languages. For example closures are quite new in C++. I know they could have been implemented if they language would have been more flexible from the start. But what if I'd like to implement a feature tomorrow that would simplify my code a lot and that relies on something that doesn't exis
<mmx87>
t in Zig?
<mmx87>
*many mainstream languages implemented them
<companion_cube>
it's pretty interesting that rust is implementing async/generators
<mmx87>
I think that's one of the pain points in C, that there's really no way to implement portable coroutines. Though Rust is also kinda in a strange spot because they decided to panic or abort on OOM, instead of returning a result.
<tralamazza>
no portable way? what about that duff's device thingimabob?
<mmx87>
They're currently implementing or have implemented an allocator trait, but the issue with that is that the community who writes new data structures usually implements them by panicking on OOM. It's more of a culture issue than of a language issue though, and I'd imagine that it can't be simply changed.
<mmx87>
tralamazza, that's portable but comes with restrictions.
<tralamazza>
like?
<mmx87>
No local variables and no nested switch usually if you don't rely on computed gotos.
<tralamazza>
yah, use the context thing for local vars
<tralamazza>
nested switches, sure, kinda feel like an edge case though
<mmx87>
Also, they're not really that stackable. How would you do multiple layers? Like if I have a function that yields but calls another function that wants to yield.
<mmx87>
How would you do that?
<tralamazza>
protothreads! that was the name
<tralamazza>
was it?
<mmx87>
Yeah
<tralamazza>
sorry i dont understand your questin
<tralamazza>
question*
<mmx87>
OK, imagine you write a function that downloads a file over HTTP. Now you could yield from that function, but imagine you have another function which handles HTTP connections and that one would yield to remain responsive. I don't think there's an elegant way to solve that in C, without assuming many details about the target architecture. It might b
<mmx87>
e have been quite simple if C would provide a way to save and restore a stack, but last time I checked there's no such way in standard C, maybe because C doesn't assume that a stack is used to implement local variables (just a hypothesis, I'm not sure if they assume the existence of a stack).
<mmx87>
(I think they wouldn't even need to assume the existence of a stack to implement a primitive who "saves the current context.")
<tralamazza>
yup still lost, i spend my days in the low level =P sorry
wilsonk__ has quit [Ping timeout: 248 seconds]
hio has quit [Quit: Connection closed for inactivity]
<andrewrk>
I haven't seen that chaining done before, it looks good
<andrewrk>
I noticed because it broke in the copy elision branch so I'm fixing that now, so also thanks for the test case
<andrewrk>
regarding the coroutines discussion above, zig's coroutines are changing to be nothing more than language-supported syntax for Continuation Passing Style
bheads has joined #zig
<scientes>
oh yeah that is cool
<andrewrk>
it's more of a general purpose tool than than people usually think of with the word "coroutines"
bheads has quit [Client Quit]
<scientes>
|| || ||
bheads has joined #zig
<scientes>
andrewrk, how does that differ from longjmp()/setjmp()?
<andrewrk>
the rewrite will remove the tight coupling of coroutines with allocators
<scientes>
that sounds like a good idea
<companion_cube>
mmx87: rust stdlib does fail on OOM, but if you use no-stdlib I think it's your choice
<scientes>
like most of zig, separating out the allocation
<companion_cube>
I think for most user land applications, failing is the simplest thing to do
<companion_cube>
(who wants to check for errors every time they `vec.push(x)`…)
<scientes>
companion_cube, its still difficult, andrew has talked about his before
<andrewrk>
longjmp/setjmp save registers and do some processor magic. CPS style is basically a state machine function with the local variables passed in via a struct parameter
<tralamazza>
composing state machines, that's a pain
<andrewrk>
right, but with language-supported syntax, it becomes pretty painless
<companion_cube>
also makes it possible to implement recursive algorithms reliably!
<scientes>
on the co-routine stack
<andrewrk>
the main problem with failing on allocation is when *libraries* do it. and the problem is when the std lib makes it not obvious when you're doing that. because then most libraries will do it and then you can't use most libraries in e.g. embedded or freestanding
<scientes>
(which is now explicitely passed around)
<scientes>
but I guess could now be null
<andrewrk>
or if you just have an application which wants to do something different
<scientes>
(and the compiler could even check that it doesn't use stack in that case!)
<andrewrk>
zig is intended to be able to make libraries that have maximum code reuse and best possible behavior / performance
<scientes>
it is already succeeding massively at that (on a prototype basis)
<tralamazza>
I am here for the explicit nature of the language
<andrewrk>
scientes, call it a "frame" rather than "stack" because "stack" implies multiple frames
<scientes>
andrewrk, oh yes, you never have more than one frame when switching co-routines
<mmx87>
>mmx87: rust stdlib does fail on OOM, but if you use no-stdlib I think it's your choice
<mmx87>
Yeah, I know. But it has more to do that there are quite a lot of good data structures which panic on OOM. It doesn't make sense to basically limit their scope of usability.
<mmx87>
The problem is more that Rust is also intended to be a system programming language.
<mmx87>
Imagine you work on a RTOS and you want to use these sleek data structures.
<companion_cube>
in which case you'll probably rewrite your own libs, I think
<andrewrk>
right - but in zig you wouldn't have to do that
<companion_cube>
(which is what you'd do in C anyway)
<scientes>
mmx87, not really, you just can't continue on OOM
<andrewrk>
and importantly - zig libraries will also be usable and you won't have to rewrite those either
<scientes>
so you have to unwind and try again with differn't settings
<scientes>
git fails miserably at this
<companion_cube>
(tbh I'm on an OS where OOM doesn't exist at all)
<andrewrk>
without overcommit, OOM is quite a recoverable error, when APIs are designed with failure in mind
<mmx87>
But that's bad engineering IMO. There are some cases where you should write your own, but having battle-tested general data structures is a good thing. I'd imagine many errors in C are related to that in C the programmer implements all the data structures from sratch.
<scientes>
and linux should be able to send a SIGBUS instead of killing when you writing to a overcommit page
<scientes>
however the program's next syscall would have to be a munmap or it would be killed
<scientes>
yeah that still might be hard to do....
<andrewrk>
perhaps, but as an application developer it would be incredibly difficult to manage failure in that way. the time you need to know if it worked or not is when you ask for the memory
<mmx87>
I think that's one of the advantages that Zig has over Rust currently. It doesn't have the cultural baggage of Rust where most people are fine with panicking on OOM.
<scientes>
andrewrk, depends, it would give you the address of the fault, and it could be handled, but certainly a non-trivial problem
<mmx87>
Otherwise it's a pretty well-designed language overall.
<andrewrk>
I agree that cultural norms are important. Here it is "sure we have bugs, but they're all fixable by design" vs "some bugs we will never be able to fix"
<companion_cube>
for most applications I still don't see what you could do.
<tralamazza>
rust needs a rewrite, smaller (again), call it redox
<companion_cube>
like in ripgrep, what to do in case of OOM?
<andrewrk>
in zig culture, bugs are human mistakes, not design limitations
<mmx87>
No, imagine Libreoffice or something like that, even normal programs should often be able to handle OOMs.
<scientes>
companion_cube, regular expression have O(1) memory usage
<mmx87>
Imagine you just crash and don't save the document. If an error is returned you might be able to save the document before exiting.
<mmx87>
That's a reasonable thing to do IMO.
<companion_cube>
depends how you implement them, and you need to keep the captured groups sometimes
<scientes>
companion_cube, that is why they are called regular
<companion_cube>
mmx87: that's the wrong design, you should have a log as in a DB if you want to be resilient
<companion_cube>
no one uses actual regular expressions
<scientes>
companion_cube, you can just store pointers, and let the data page out
<andrewrk>
failure matters when there is more than one operation happening, and failure in one operation should not affect failure in another one
<andrewrk>
*recovering from failure matters
<scientes>
companion_cube, yes they do, that is exactly why RE2 was written
<scientes>
and hyperscan
<companion_cube>
really? so they don't have capture groups or similar things? :o
<andrewrk>
for example in a web server, you would not want to crash on OOM. you would want to fail a single request with "500: internal server error" and then complete the other requests successfully
<scientes>
companion_cube, you can store pointers to the start and end of the capture group, its still O(1) memory
<companion_cube>
that implies you have the string in memory though.
<scientes>
companion_cube, or offsets into a file
<andrewrk>
well O(N) where N is how many capture groups you have. but that can probably be statically limited to 100 or something
<tralamazza>
overcommit is shifting the problem around afaict
<scientes>
its the same as a pointer
<scientes>
tralamazza, its deferring the problem, which makes sense in some cases
<scientes>
just like a gc
<andrewrk>
overcommit is a step away from a real time capable system
<scientes>
andrewrk, its O(1) for a single regexp
<scientes>
but its O(n^2) to the length of the regexp
<mmx87>
>mmx87: that's the wrong design, you should have a log as in a DB if you want to be resilient
<mmx87>
Even if you save it periodically I don't think that it's just fine to crash on OOM. The right behaviour is the leave the choice to the programmer on what to do on OOM. Everything else is just limiting the usability of a programming language.
<scientes>
but that O(1) is the definition of regular languages, as defined by Noam Chomsky
<scientes>
O(1) time and space, a finite-state-automata
<companion_cube>
I mean checking a regex against a string is O(n) and constant space… once you've built the automaton
<mmx87>
I think one of the issues with overcommit has also to do that programmers just write their programs with the assumption that it gets killed anyways under Linux when an OOM occurs.
<mmx87>
Which is quite dangerous.
<andrewrk>
btw I had a memory bug yesterday while debugging code and it used all my memory and entire system froze. had to hard reboot. that's a horrible design, it should have only killed the runaway process
<scientes>
oh yes O(n) time, my bad
<companion_cube>
(which can explode during removal of non determinism)
<andrewrk>
oom killer doesn't even work
<scientes>
yeah oom killer blows
<companion_cube>
I'm using one in userland because of that, yeah
<andrewrk>
alright let's see what lovely regression is next for me in this branch...
<mmx87>
andrewrk, I think the issue under Linux is with the OOM that when the OOM killer gets activated too late when everything is swapping already and then it feels like a "freeze." That's really bad design, one of the annoying things on Linux that it optimistically overcommits.
<companion_cube>
(btw rust has some issues open to turn OOM into panics, which are per-thread and recoverable)
<tralamazza>
maybe it's the mental model programmers have of a computer. closer to the metal, memory is very much finite, allocation is something that may happen. in lisp-land, everything is infinite machine
<tralamazza>
so for me overcommit is bonkers
<mmx87>
Yeah, I know. But they go into the territory why Rust doesn't use exceptions as error handling mechanism. Maybe it's the right thing to do for OOMs, but I feel it makes everything less transparent for the programmer.
<companion_cube>
well OOM is a pretty exceptional condition
<mmx87>
Doing something like unwrap isn't really that much effort.
<companion_cube>
(unless you target microcontrollers, but then just don't try to use fancy libs)
<tralamazza>
exceptions open the flow control can of worms
fu5ha has joined #zig
<fu5ha>
hi! So I'm trying to use cglm (https://github.com/recp/cglm) with zig, and running into problems pretty quickly ;p so if I create a variable of type `c.vec3` (or any of the other cglm types, which are just typedefs for arrays of floats) then attempt to use them in cglm functions, the compiler complains about the variable type
<fu5ha>
since the function is expecting a c pointer but is receiving a pointer to an array of floats
<fu5ha>
i.e.: main.zig:8:42: error: expected type '[*c]f32', found '*[3]f32'
<fu5ha>
anyone know if there's an ergonomic way to make the compiler happy here?
<andrewrk>
mmx87, I have swap disabled and 8 GiB RAM
<andrewrk>
fu5ha, hmm that certainly looks like a bug - missing implicit cast
<mmx87>
I wish they would solve that problem realistically. But as it's mostly used on servers I'm not sure if they care that much. You can usually start the OOM manually with the sysrq sequence when you have it enabled. Never failed me.
<andrewrk>
fu5ha, I don't see an issue, I'm going to open one for you
<fu5ha>
andrewrk, ah, thought it seemed like it should be able to implicitly cast. What would I do to explicitly cast it here properly? And thanks!
<andrewrk>
is this master branch btw?
<companion_cube>
on a server you probably want to die and be restarted by systemd
<fu5ha>
seems like that function should be able to be comptime-evaluated to me?
fu5ha has quit [Ping timeout: 246 seconds]
fu5ha has joined #zig
<fu5ha>
andrewrk, any chance you could point me to the relevant area of the code where the implicit casts are/should be implemented?
Ichorio has joined #zig
wilsonk has joined #zig
<fu5ha>
also as far as the comptime thing, I figured it out
<fu5ha>
just needed to figure out where to put the comptime keyword :p
<scientes>
i'd like to make it an annonymous enum
<scientes>
.comptime
<scientes>
instead of a reserved word
<scientes>
.volatile too
<fu5ha>
think i might have found another bug x)
<andrewrk>
It might be possible to improve zig so that when using a comptime var, any expression which uses it is implicitly evaluated in a comptime context
<fu5ha>
no idea where the `pub const m = 4;` is coming from though
<andrewrk>
Looks like a translate-c issue where it's not dealing with name collisions
<Tetralux>
> when using a comptime var, any expression which uses it is implicitly evaluated in a comptime context
<Tetralux>
That does seem useful.
<andrewrk>
Really the only difference in a comptime context is that function calls are invoked
<Tetralux>
Meaning, using a comptime var in a func call doesn't work, unless you mark the call as comptime?
<Tetralux>
In which case yeah, unless I'm missing something interesting, you prob always would want that call to be comptime too eh.
<fu5ha>
also andrewrk, for the implicit-cast thing from earlier, someone on discord had the idea of doing array[0..].ptr, which also seems to work as a workaround for now and is less ugly than using @ptrCast everywhere :)
<andrewrk>
That's a little better but it's still a workaround. The issue will be fixex
<andrewrk>
*fixed
<fu5ha>
indeed ^_^
<fu5ha>
is there a way for me to use cglm directly as a C lib rather than using translate-c for now?
<andrewrk>
fu5ha, you can do an offline translate-c and then patch up the output zig code and commit that to your repo
<fu5ha>
ah, that's a good idea
<andrewrk>
e.g. you can just copy that file that it listed in the compile error
<fu5ha>
right
<andrewrk>
someday that workaround won't be necessary, but there are a lot of TODOs in translate-c today
<fu5ha>
:thumbsup:
fu5ha has quit [Remote host closed the connection]
fu5ha has joined #zig
wootehfoot has quit [Read error: Connection reset by peer]
marijnfs__ has joined #zig
marijnfs__ has quit [Ping timeout: 258 seconds]
marijnfs__ has joined #zig
Ichorio has quit [Ping timeout: 250 seconds]
<fu5ha>
if I made a type like `const vec2 = [2]f32;` then how can I express a that an argument to a function should be a constant of this type? I tried `fn blah(a: const vec2)` and `fn blah(const a: vec2)` but neither compile
<emekankurumeh[m]>
all arrays are const unless stored as a var
<emekankurumeh[m]>
i.e. [2]const f32 is invalid
halosghost has quit [Quit: WeeChat 2.5]
<mikdusan1>
is it possible due to aliasing, that zig statements might eventually get re-ordered?
bheads has quit [Quit: bheads]
<daurnimator>
mikdusan1: could you rephrase the question?
halosghost has joined #zig
<mikdusan1>
in ArenaAllocator.deinit() there is `it = node.next;` and next stmt `self.child_allocator.free(node.data);` frees node
<mikdusan1>
i'm trying to debug something on copy-elision-3 and for the life of me cannot figure out why `it = node.next` is segfaulting.
<mikdusan1>
currently following hint: if i disable the free, i can actually build zig.exe
<mikdusan1>
basically alloc anything on arena and deinit segfaults
<emekankurumeh[m]>
can you try deiniting manually without the defer?
<mikdusan1>
emekankurumeh[m]: still faults
<emekankurumeh[m]>
nvm
<scientes>
do enums have any guaranteed order?
<scientes>
because they shouldn't
<Tetralux>
you mean the order that they are listed in the typeinfo I'm guessing
<scientes>
the order they are in the source file
<scientes>
in C this is defined and aplications depend on it
<andrewrk>
a decent chunk of std lib tests passing in result loc branch :)
<andrewrk>
mikdusan1, aliasing / moving memory loads/stores around is not something that happens in debug builds
<andrewrk>
I was about to look at that arena allocator test failure, do you have any clues so far?
<andrewrk>
ah you have a reduction, taking a look
<mikdusan1>
yes just force arena to deinit at least 1 allocation
<andrewrk>
I'm going to try to reduce it further
<andrewrk>
it's probably invalid llvm ir code generated
<andrewrk>
I mean, valid llvm ir but something incorrect, like not initializing a variable
<andrewrk>
scientes, I think that's worth discussing in a proposal
<andrewrk>
I think that is not yet stabilized as far as language spec goes. the stage1 compiler will do them in order
<scientes>
yeah better than a specification is just to have debug mode make them random
<andrewrk>
right - debug mode would do that if we decided in the lang spec that the order is not defined
<andrewrk>
so the first step is figuring out how it's supposed to work
<andrewrk>
there is no lang spec yet, but I mean, making a decision to eventually write down in the spec
<scientes>
Its also hard to support enums as flags (which people do in C) without adding ugly footgun UB
<andrewrk>
mikdusan1, a hint is that this is a regression. it works in master and it should probably work exactly the same way. so if you can observe a difference between master and this branch that can narrow in on the issue
<scientes>
or too much semantic analysis
<andrewrk>
enums as flags doesn't make sense to me, it's not the correct type
<andrewrk>
packed struct with u1's would make more sense to me. if we had the struct equivalent of enum literals that would be reasonable I think
<scientes>
yeah you can just do a struct with some bits reserved
<andrewrk>
yeah and we have defaults now
<scientes>
and specific enum values
<andrewrk>
then you @bitCast it to a u32 or whatever. in theory it should generate the same code
<scientes>
or union it to u32
<tgschultz>
but can you or the structs together?
<scientes>
a struct inside a union
<tgschultz>
an extern union you mean
<scientes>
yes
<tgschultz>
still wouldn't allow `const x = A|B|C|D;` though, you may as well just use consts.
<scientes>
oh yes
<scientes>
@enumToInt() | cnst
<scientes>
translate-c needs this
<scientes>
ability to lower enums to ints
<tgschultz>
I suppose one could just implement that as a member func, and it could look like this: `const x = Bitfields.combine(.A,.B,.C,.D);` `if(bitfields.has(.C)) @panic();`
<tgschultz>
also allowing distinct int types would make it kind of a non-issue too.
<andrewrk>
yeah distinct int types would better model the code than enums
<andrewrk>
I think that bugs with flags are pretty rare though
<andrewrk>
I'm not sure even anything needs to be done
<mikdusan1>
andrewrk: ok, i have enough to keep going myself on this; new hint `it = node.next` actually *modifies* node.next :)
marijnfs__ has quit [Quit: WeeChat 2.3]
<andrewrk>
mikdusan1, nice, ok I'll look for a different bug to work on then
marijnfs_ has quit [Quit: WeeChat 2.4]
<Sahnvour>
just a thought: pure random enum values makes for non deterministic builds, and also hinders the ability to do incremental recompilation
<andrewrk>
debug builds are allowed to be nondeterministic but the other ones are deterministic
<andrewrk>
precisely to help with incremental recompilation
<Sahnvour>
does release-safe count for debug in this case ?
<andrewrk>
no, that one is required to be deterministic
<andrewrk>
debug mode is the only one optimized for compilation speed
<Tetralux>
> "debug builds are allowed to be nondeterministic"
<Tetralux>
That doesn't sound very good.
<fu5ha>
so how would i go about modifying an array that is a member variable of a struct
<Sahnvour>
feels weird to have debug builds, partly intended for automatic testing, being non deterministic
<Tetralux>
Surely if you're debugging, you want anything _except_ nondeterminism.
<fu5ha>
like struct { pub a: [2]f32; }
<andrewrk>
Tetralux, Sahnvour - I can see how that could be an issue
<Sahnvour>
I'm not sure you're implying that, but I doubt we have to sacrifice determinism for speed of compilation
<andrewrk>
consider incremental linking: the idea is to leave extra space in case functions grow or shrink
<andrewrk>
this is a form of nondeterminism
<andrewrk>
msvc linker does this
<andrewrk>
likewise you could leave extra space in structs in case fields are added or removed
<andrewrk>
this is also how hot code swapping would work - it's necessarily nondeterministic
<Sahnvour>
I think for incremental linking it generates functions that are just proxies with a call instruction that gets patched, but I get your point
<Sahnvour>
however you can still disable it if you want to stay deterministic in this case
<andrewrk>
yeah I think that use case is valid - you have a bug and you want to reproduce it in debug mode
<andrewrk>
I think it might just be all fine if "randomness" is deterministicly seeded
<Sahnvour>
yes, this is totally acceptable
<andrewrk>
yeah that's the plan
<Sahnvour>
good then, if you can at least get/set the seed, everything is reproducible
<Tetralux>
Personally, I'd be fairly strongly inclined to not have any randomness anywhere near my builds xD
<emekankurumeh[m]>
sort of like fuzzing, but built into the compiler?
<emekankurumeh[m]>
fu5ha have you tried assigning an instance of the struct and modifying that?
<andrewrk>
Sahnvour, except if you were to, e.g. make a function much bigger and then make it smaller again, you'd get a different build than before
<Sahnvour>
assuming there is some pseudo randomness in the compilation, this probably means you need to have the whole test suite run two times, one with a fixed seed, and one with a new seed at every run
<andrewrk>
why's that?
<fu5ha>
@emekankurmeh[m], yes, this is within a method, i.e. something like this https://paste.rs/VZe
<fu5ha>
'method'
<Sahnvour>
because otherwise it could happen that previously undiscovered bug pop up on totally irrelevant changes for example
<andrewrk>
ah I see. yeah I see emekankurumeh[m]'s point now, it's a lot like fuzzing
<Sahnvour>
having a static baseline helps you identify where it comes from
<andrewrk>
the baseline would be a clean build
<andrewrk>
it's more to do with the fact that debug builds are stateful in order to go faster
<Tetralux>
Is there a switch to make everything from scratch?
<Tetralux>
Also I'm not sure they _have_ to be stateful for that.
<andrewrk>
Tetralux, we're talking about vaporware - zig does not do any of this stuff yet
<andrewrk>
zig master branch builds are stateless in all modes
<Tetralux>
Okay gotcha xD
<andrewrk>
Tetralux, that's true. maybe stateless can be an option. (it would always be on for non-debug builds)
<Sahnvour>
in my previous job we had automatic tests that had non deterministic failures, and it was a pain in the arse :D
<andrewrk>
noted
<andrewrk>
I think this might be worth writing up in an issue. I hadn't considered that "stateless vs stateful builds" were different concepts than caching
<andrewrk>
because you can still do some caching with stateless builds
<andrewrk>
but stateful builds let you aggressively cache more
<Sahnvour>
can you give an example of what you think of by stateful/less during compilation ?
<andrewrk>
stateless would mean that if you have the same input you get the same output. deterministic. LLD does that kind of linking
<andrewrk>
stateful would keep track of struct padding, existing executable section sizes & space for functions to grow and shrink, so that less work would have to be redone on subsequent builds
<Sahnvour>
ok, so state that outlives the compilation process, typically zig-cache ?
<andrewrk>
zig-cache as it stands is "stateless"
<andrewrk>
because we do the cache hash stuff to find out if the output would be different
<andrewrk>
but yes stateful would be state that outlives the compilation process, and also affects the output of subsequent builds
<Sahnvour>
right, so I feel like [non-]deterministic would be a better fit, since caching data structures to speed-up does not necessarily introduce a difference in the output. but I understand
<andrewrk>
that makes sense, and I agree that's a better word for it
<fu5ha>
I feel like I'm either missing something simple or am trying to go down a path that is impossible, but is there a way to make something like this work `for (self.a[0..2]) |v, i| v += o.a[i]` where self.a is a `[2]f32`?
<andrewrk>
fu5ha, you're trying to modify the element yes?
<andrewrk>
variable bindings are like parameters by default: they might be a reference or a value but they act like a value
<fu5ha>
doesnt work because I still get a `*const f32`
<fu5ha>
er wait
<fu5ha>
maybe I need to not slice it
<Sahnvour>
andrewrk: indeed, I remember reading this now. I'd still like to insist one last time that whenever determinism can be preserved, we should strive for it :)
<andrewrk>
Sahnvour, thanks, I'll write up an issue for this at some point, I think you have raised some important points here
<Tetralux>
+1
<andrewrk>
feel free to start the issue if I don't get to it soon
<andrewrk>
fu5ha, your `self` pointer is probably const. which means self.a is const. which means v is const
<fu5ha>
ah. so I guess I can 'rebind' self as var?
<andrewrk>
fu5ha, I found your code link above. pub inline fn plus_ip(self: Vec2(T), o: *Vec2(T)) Vec2(T) {
<andrewrk>
this will let you mutate `o`
<fu5ha>
aha, ok
halosghost has quit [Quit: WeeChat 2.5]
<fu5ha>
thanks :D
<andrewrk>
btw you should delete all those inlines probably
<andrewrk>
if you're doing it for perf reasons, you are actually tying the optimizer's hands down by doing that
<andrewrk>
trust the optimizer's inliner, it's really good
<andrewrk>
maybe I should rename that keyword to `forceinline` so that people think twice
<andrewrk>
everyone will come to the issue tracker to complain about it, and discover the docs for why they don't need it
<Tetralux>
and everyone will use it anyway because they won't trust the optimizer xD
<andrewrk>
inline is the programmer's good luck charm
<fu5ha>
Haha ok, will do :)
<Tetralux>
andrewrk, I think it's because in C, it's just a hint, and people want determinism... and because funcs that are two lines long seem good to inline.
<Tetralux>
*grins*
<emekankurumeh[m]>
does zig always pass by reference for function arguments?
<AlexMax>
16 hits for __forceinline in one source file
<andrewrk>
AlexMax, doom came out in 1993. compilers have come a long way since then
<AlexMax>
andrewrk: This is a modern port that has active maintainers
<andrewrk>
ah
<AlexMax>
I also see two functions that contain inline assembly
<andrewrk>
well fair enough. if you bench the perf and then try inline and it improves something, fine
<Sahnvour>
andrewrk: something to mention in the determinism issue just occurred to me: there's a higher level of determinism that is highly desirable (and more involved), execution determinism. Not only the output is exactly the same, but the compiler does the exact same trace. Really useful for debugging.
<andrewrk>
Sahnvour, I agree - it would be difficult to debug issues with multithreading on
fengb has joined #zig
<Sahnvour>
re __forceinline: nowadays that's mostly cargo cult I guess
<fengb>
Does doom really need optimization? Are they running it on a toaster?
<Tetralux>
The classic response: "You'd be surprised."
<AlexMax>
fengb: Doom's software renderer is _very_ CPU intensive, and walls are usually rendered a column at a time, which is not terribly cache-friendly.
<Tetralux>
Plus, you'd probably do that even if that wasn't the case. Gotta meet them 7ms time quotas man
<AlexMax>
There's also some overdraw done for sprites and two-sided transparent walls.
<fengb>
It makes sense in 1992... but the engine been extended in ways that require more handtuning?
<AlexMax>
At 320x240, it's fine. At HD resolutions, you start running into trouble even on somewhat modern systems.
<fengb>
Then again, I hand tune a bunch of really silly things so who am I to judge
<fengb>
Ah
<fengb>
Serious question: how does C do struct padding? I can create a "struct { uint32_t foo:8 }" and it comes out to be 4 bytes. Where do the 24 extra bits go?
<Sahnvour>
is it because of uint32_t's required alignment of 4 ?
<fengb>
Seems like it. But I can't find a reference in the spec
<fengb>
"An implementation may allocate any addressable storage unit large enough to hold a bit- field. (and later) There may be unnamed padding at the end of a structure or union."
<AlexMax>
Sunder MAP10: The Hag's Finger. 39fps at 1920x1200. If I turn around, I get into the hundreds.
<fengb>
And __forceinline means really inline, unlike the inline keyword?
<AlexMax>
Correct. inline is merely a suggestion. Do modern C compilers even pay attention to `inline`?
xcko has joined #zig
<xcko>
just built zig 0.4.0 on aarch64 alpine 3.10 (musl libc) and I can't replicate https://github.com/ziglang/zig/issues/2084. `./zig targets | grep native` "musl (native)"