<Snektron>
Every time i write C i find myself missing it
<ifreund>
try, defer, and errdefer alone make me never want to start a new project in c again
marijnfs has joined #zig
marijnfs_ has quit [Ping timeout: 256 seconds]
ur5us has quit [Ping timeout: 246 seconds]
<andrewrk>
the CI is green for the llvm10 branch
ur5us has joined #zig
dingenskirchen has quit [Remote host closed the connection]
ifreund has quit [Ping timeout: 250 seconds]
marijnfs_ has joined #zig
marijnfs has quit [Ping timeout: 246 seconds]
daex has quit [Ping timeout: 250 seconds]
daex has joined #zig
adamkowalski has joined #zig
adamkowalski has quit [Quit: Lost terminal]
plumm has joined #zig
<plumm>
andrewrk: really quick, do you like sourcehut builds or azure pipeliens better?
<andrewrk>
azure pipelines is better because they give us 6 hours and ~8 GiB RAM. source hut is better because it lets you ssh in after a failed build, and it's open-source and not owned by microsoft
<plumm>
okay, so it seems that if resources aren't really a requirement sourcehut is just the better alternative… thanks!
<andrewrk>
plumm, oh, one more benefit of azure, is that it has windows and macos support
<andrewrk>
but if you don't need that, then yes, I would recommend sourcehut
<plumm>
yeah, mainly linux+musl stuff for work; does sourcehut have caching support?
<andrewrk>
I'm not aware of it. zig uses wget on a manually created .tar.xz file for the cache
<plumm>
bah, the reason we're switching from github actions is because they have terrible caching support; seems like azure is the way to go on this one, thanks for your insight though!
<andrewrk>
I also am not aware of any caching that azure provides. on azure zig does the same thing: wget a .tar.xz file
waleee-cl has quit [Quit: Connection closed for inactivity]
adamkowalski has joined #zig
adamkowalski has quit [Quit: Lost terminal]
mikdusan has quit [Ping timeout: 256 seconds]
mikdusan has joined #zig
<euantor>
I believe sr.ht is/has been planning caching support
_Vi has joined #zig
ur5us has joined #zig
daex has quit [Ping timeout: 240 seconds]
daex has joined #zig
_Vi has quit [Ping timeout: 246 seconds]
marijnfs has joined #zig
marijnfs_ has quit [Ping timeout: 256 seconds]
dddddd has quit [Remote host closed the connection]
ur5us has quit [Ping timeout: 260 seconds]
Kingsquee has joined #zig
<Kingsquee>
where is the compiler's code for the u#/i# fanciness
<Kingsquee>
I found the definition of integer in all_types.hpp but haven't found any implementations
Ichorio has joined #zig
<Kingsquee>
I ask because I'm playing with ways of hopefully compressing/decompressing signed integers into the minimum number of bits, like 0 -> 00, 1 -> 01, -1 -> 11 without branching
marijnfs_ has joined #zig
<mq32>
Kingsquee:
<mq32>
you can just use @Type to forge your own integer types at comptime
<Kingsquee>
mq32: yeah I know, I've been playing with that too
<Kingsquee>
but I'm just curious on the technicalities of how zig would handle ops on a u2/i2
<mq32>
afaik that's just an LLVM feature
Ichorio has quit [Read error: Connection reset by peer]
<mq32>
so you declare a register u2
<mq32>
and LLVM does the magic
<Kingsquee>
...does a u2 actually use two bits then?
<Kingsquee>
or does it just wrap a u8
<Kingsquee>
is there some way to inspect the binary of a zig type?
TheLemonMan has joined #zig
<TheLemonMan>
Kingsquee, LLVM expands the result to the type ABI size, performs the op on that and then chops the extra bits
<Kingsquee>
hm
<TheLemonMan>
every type has a "size" (in bits, eg i2 -> 2) and a ABI size (in bytes, eg i2 -> 1 byte)
<Kingsquee>
can't *just* chop it though, because sign bit
<Kingsquee>
which is the part that's perplexing me for my little brain twiddle
<Kingsquee>
doesn't seem to be a branchless way to convert from a -1i8 to/from a -1i2
<TheLemonMan>
sign bit? everything's using two complement
<TheLemonMan>
-1'i8 => 0xff and -1'i2 => 0x03 ?
<TheLemonMan>
pixelherodev, check out master, I've sent a PR to fix your problem with the stack traces
<Kingsquee>
MSB is only set when value is negative so I'm being very fluffy with my terminology
<TheLemonMan>
so...are you using the sign+magnitude format?
<Kingsquee>
TheLemonMan: sorry, brain fart, realized I was forgetting about signed righ-shift behaviour
<frmdstryr>
Yeah it doesn't work very well for what I'm trying to do either, unless I use `usingnamespace` which I'd rather avoid
<andrewrk>
2206 gives zig tooling the property that it can correctly find all the source files that belong to a given compilation without doing semantic analysis
doublej41 is now known as doublej472
adamkowalski has joined #zig
adamkowalski has quit [Ping timeout: 256 seconds]
marijnfs has quit [Ping timeout: 240 seconds]
ifreund has quit [Quit: WeeChat 2.7.1]
adamkowalski has joined #zig
redj has quit [Ping timeout: 256 seconds]
ifreund has joined #zig
companion_cube has quit [Quit: WeeChat 2.3]
FireFox317 has joined #zig
mahmudov has quit [Ping timeout: 260 seconds]
adamkowalski has quit [Ping timeout: 260 seconds]
adamkowalski has joined #zig
mahmudov has joined #zig
companion_cube has joined #zig
redj has joined #zig
adamkowalski has quit [Ping timeout: 250 seconds]
adamkowalski has joined #zig
adamkowalski has quit [Client Quit]
plumm has quit [Quit: Lost terminal]
dimenus has joined #zig
tankman has joined #zig
<TheLemonMan>
andrewrk, why is Thread.spawn handling the whole stack allocation business even when we're using pthreads?
<andrewrk>
TheLemonMan, because of future plans for zig to know upper bound stack size of functions
<andrewrk>
llvm makes this a bit tricky, but solving this is going to be a key point of zig's strategy for safety/correctness with regards to stack overflow
<TheLemonMan>
eh tbh I don't think that's possible at all, the effective stack usage is determined after the codegen is done
<TheLemonMan>
and that's if you don't take into account alloca and friends
marijnfs has joined #zig
<andrewrk>
that makes it possible, but not a "comptime" value - the stack size would be a relocation like anything else
<andrewrk>
alloca is not allowed in zig; external functions will be annotated (with a default) stack size that they expect to have available when called, safety checked when called
<andrewrk>
there is good reason to be skeptical of this working smoothly. I agree we will likely run into problems. but I still think it's worth a try
<mikdusan>
blah: llvmorg-10.0.0-rc6
<TheLemonMan>
yeah that's the spirit, innovation and experimentation is always good
<andrewrk>
mikdusan, ah, you saw it before I did. damn, I have this blog post ready to go out and everything
dimenus has quit [Remote host closed the connection]
ifreund has quit [Ping timeout: 256 seconds]
<TheLemonMan>
andrewrk, speaking of threads, what do you think about always allocating some TLS state?
<TheLemonMan>
the idea is to stash there some infos we need w/o having to do one more syscall (think of thread ID) and to enable the stack protectors
ifreund has joined #zig
Akuli has joined #zig
<andrewrk>
I think we should consider carefully before introducing a dependency on TLS
<andrewrk>
but I'm not necessarily against it
<andrewrk>
I don't fully understand this particular use case
<andrewrk>
what does TLS have to do with stack protectors?
<andrewrk>
looks like LLVM is now planning to tag 10.0.0 tomorrow
<TheLemonMan>
cookies are per-thread and are stored in the TLS
slowtyper has quit [Quit: WeeChat 2.7.1]
slowtyper has joined #zig
<companion_cube>
is there an interface for iterators yet?
<companion_cube>
(with a loop syntax)
<fengb>
No but the de facto pattern is `var iter = thing.start(); while (iter.next()) |item| {`
<traviss>
i just built mpfr with drop-in zig cc. no issues. nice job!
tankman has quit [Quit: Leaving]
<andrewrk>
TheLemonMan, I do think it would make sense that we would have the concept of whether a target supports TLS. for some targets, they clearly do, and we could take advantage of it at virtually no cost
<companion_cube>
fengb: that's a bit sad :p
<TheLemonMan>
oh well, the only place where that matters is linux w/o libc
<TheLemonMan>
glibc and musl already allocate TLS unconditionally
<TheLemonMan>
and bare-metal targets are out of scope here
<andrewrk>
yeah that's what I mean; I do think it's ok to depend on TLS there
<andrewrk>
iterator interfaces drive me nuts. I love that zig doesn't have one
<fengb>
With capture and optional, I'm inclined to agree
<andrewrk>
just do the thing. why you gotta make a big performance art out of it
<fengb>
I do slightly wish we could do `for (thing.start())` just to save that one line >_>
<andrewrk>
you can save as many lines as you want, just delete the line breaks
<fengb>
zig fmt says no
<ifreund>
zig fmt is god
<andrewrk>
oh yeah! I forgot we deleted that excuse I just made
<companion_cube>
:DDDD
<companion_cube>
I mean, it's very natural to have that in a language
<ifreund>
honestly the only thing that bugs me about the current state is that the iterator/counter variable is valid outside the scope of the loop
<andrewrk>
excuses?
<andrewrk>
it's perfectly reasonable to introduce an additional block scope
<andrewrk>
but that goes for all variables, not just loop counters
<ifreund>
fair enough
<companion_cube>
but then each loop is 2 scopes deep
<andrewrk>
{var i: usize = 0; while (i < 10) : (i += 1) {
<andrewrk>
}}
<andrewrk>
maybe zig fmt should allow this
<fengb>
🙃 `while (var i: usize = 0) : (i < 10) : (i +=1 ) {`
<andrewrk>
what if you want 2?
<fengb>
Comma operator right?
<andrewrk>
that's not even fewer characters than mine
<andrewrk>
you want special syntax so that you can make 2 extra keystrokes?
<fengb>
I'm joking... it's basically the C syntax
<andrewrk>
you're joking but you represent a non-trivial amount of people who aren't joking
<ifreund>
the comma operator is horrible
<mq32>
andrewrk: I'd be happy to see an option to not spill an iterator variable as well
ur5us has joined #zig
<mq32>
but it's not a "must have", but a low would-be-cool
<companion_cube>
more readable, less error prone
<mq32>
the last point is the thing for me
<mq32>
if i don't spill the variable into the outer scope, i can prevent accidental usage
<companion_cube>
same flaw as python
<mq32>
makes code reviews a lot easier
<andrewrk>
I will concede that in practice, with zig's while vs C's for, iteration variables do end up spilling more often, which is undesirable
<companion_cube>
`while (var x = iter.start()) : (…) {…}` would do I guess
<mq32>
companion_cube: i immediatly don't like it because it's not clear what the condition is
<traviss>
is there a proposal for `if (var x = 1; x < 10)` ?
<fengb>
Random thought, what about leveraging a `with` expression? `with (foo.start()) |iter| while (iter.next()) |item| {`
<fengb>
Maybe not... looks like line noise after I typed it out
<traviss>
i like andrew's suggestion of zig fmt putting it on one line
<marijnfs>
to iterate with an integer you have to define it before the while right?
<andrewrk>
ifreund, I agree the name of TailQueue is odd. I think I'd like to put it back to DoubleLinkedList
<marijnfs>
it gets a bit annoying as its in the scope
<ifreund>
andrewrk: I can send you a PR sometime tonight/tomorrow if you like. I'm always down for some soild name bikeshedding :D
<andrewrk>
you should have a chat with daurnimator first though, I believe he managed to convince me to change the name to TailQueue
<andrewrk>
but every time I see the name I become less and less convinced
<ifreund>
man 3 queue has some info
<ifreund>
tbh daurnimator is right, what we have is a tail queue
<ifreund>
if we removed the pointer to the last node it'd just be a doubly linked list
<ifreund>
technically it's a doubly linked tail queue though, since you can have singly linked ones as well
<ifreund>
so, I guess I'd be for adding the doubly linked list and singly linked tail queue for completeness :D
<marijnfs>
aren't linked lists in most cases quite slow? since your memory ends up all over the place
<ifreund>
they have there uses, for example when pointer stability is required
<ifreund>
O(1) ordered removal as well
<TheLemonMan>
you can always preallocate many nodes in a contiguous slab of memory
<ifreund>
s/there/their/ (i'm aweful at spelling)
<ifreund>
so if I had my way with linked_lists.zig, we'd end up with SinglyLinkedList, SinglyLinkedTailQueue, List, and TailQueue
<andrewrk>
marijnfs, there are tradeoffs in either case; it really depends on your use case. what linked lists do that arraylists cannot, is that linked lists can be "intrusive" which allows you to "bring your own memory" when putting a node in the list
<andrewrk>
as an example, you can have a linked list with 3 nodes: 1 statically allocated, 1 allocated on the heap, and another allocated on the heap but with a different allocator
<andrewrk>
particularly useful is when a linked list node is allocated as part of a function's @Frame()
<marijnfs>
true, that sounds kinda nuts though:P
<marijnfs>
ok then it makes more sense
<andrewrk>
this is how std.event.Loop works without the possibility of failure
<andrewrk>
I mean at least failure due to OOM
<marijnfs>
i guess you can do it in an array_list with some type that takes care of the indirection
<marijnfs>
ah you mean the whole node lives in some other memory
<andrewrk>
yes. this is not possible with arraylist
Akuli has quit [Quit: Leaving]
<marijnfs>
indeed
<jaredmm>
Should the WinSock2 code be exposed in std/os/Windows.zig? Right now system.socket and etc on Windows don't exist.
<jaredmm>
There's already some socket stuff there, so I assume yes, but I wasn't sure if there was a reason the std/net.zig usages aren't using the ws2 calls.
<andrewrk>
I still need to learn how networking works on windows
<andrewrk>
your best bet right now is making your own abstractions or using a c library
<jaredmm>
My current abstract is about 15 defines inside an ifdef for Windows or *nix, lol
<marijnfs>
zeromq might have some hints on how to do it?
<marijnfs>
they got networking down pretty well
<companion_cube>
libuv could be a good way to go
<jaredmm>
Mine certainly isn't graceful. I've got macros defined for all the Unix socket functions that take in a file description and (on Windows) looks up a value in an array to get the SOCKET value (uint pointer).
<jaredmm>
Then it just runs the WSA calls it needs to and everything seems like it works, so I don't look at it too closely.
<BaroqueLarouche>
IIRC from my university course on networking, WinSock is basically UNIX socket but you need to call some extra functions to make it work
<jaredmm>
Yeah, I think it was based on BSD code or something like that. There's some extra init/cleanup that gets defined away as well.
<ifreund>
is there a way to debug assert that all memory in a struct is defined?
<TheLemonMan>
Trumpet Winsock
<ifreund>
well I'm not sure if that's technically possible ouside of some kind of compiler magic
<ifreund>
nothing stops me from assigning 0xaa to things
<andrewrk>
hmm one could wrap libuv with zig APIs using async/await and that would work pretty well
<andrewrk>
ifreund, even better - assign undefined to things. it will assign 0xaa in the appropriate modes as well as put metadata there that makes tools such as valgrind aware that the bytes are undefined
<TheLemonMan>
ifreund, the valgrind module lets you declare arbitrary chunks of memory as defined/undefined
<andrewrk>
even better though, @memset with `undefined`
<andrewrk>
or assign the struct directly
<ifreund>
i'm aware of `undefined` in zig and that zig puts 0xaa in everything in debug mode
<andrewrk>
it would be possible to add a language builtin that detects if a value is undefined. it would have false negatives but no false positives
<ifreund>
i have a struct that is initialized = undefined and is then later assigned data to all of its fields
<andrewrk>
some planned safety features will use this builtin internally
<ifreund>
i was looking for a way I could assert that every field has been assigned a value
<andrewrk>
I was thinking about the same problem recently. I haven't come up with a solution yet
<andrewrk>
we have the ability to put a secret field in structs to detect undefined, but yes the question is when would it get set
<andrewrk>
maybe `x = undefined` would be distinct from `x = .{ .every_field = undefined}`
<ifreund>
hmm, that sounds confusing. I'd argue those should be equivalent
<ifreund>
i'd say the secret field should only be set to "struct is defined" once all fields of the struct have been assigned something that isn't `undefined`
<daurnimator>
ifreund: "tail queue" is what doubling linked lists are called in C
<daurnimator>
ifreund: see /usr/include/sys/queue.h
<ifreund>
daurnimator: yeah I found the man page for that
<ifreund>
i'm 100% with you
<ifreund>
it is a little more nuanced than "tail queue is the C word for doubly linked list" though
<daurnimator>
yeah there's also circular doubly linked list
daex has quit [Quit: /me 's znc kicks the bucket]
<daurnimator>
and then you'll find LinearFifo... which is what you actually want a lot of the time (if you're not using intrusive linked list or your list items aren't variably sized)
daex has joined #zig
<tdeo>
is there another name for the std.SegmentedList data structure? it's really useful but i can't find anything online about it
TheLemonMan has quit [Quit: "It's now safe to turn off your computer."]
<tdeo>
(writing some rust with Pin and wondering if anyone has made something similar, actually)
<mq32>
andrewrk: i just had a random thought crossing my mind
<mq32>
is it possible to use std io APIs in non-blocking/async mode when writing a library?
<andrewrk>
a zig package right? as opposed to libfoo.so
<mq32>
no, a lib with C api
<mq32>
so something like "lib_open(), lib_pumpEvents(), lib_close()"
<andrewrk>
tdeo, I'm not aware of anything. I sort of just had the idea of that data structure and coded it up one day. I didn't read any articles about it
<andrewrk>
mq32, ah, yes, if the C library exposes certain kinds of abstractions, then it's possible to wrap it with a zig API that integrates an event loop
<mq32>
but the core design right now is to have exactly one main loop, right?
<andrewrk>
right, but you can't really help what goes on on the other side of the C ABI boundary
<mq32>
yeah, i know
<mq32>
i'm asking because i write a library atm that has a non-blocking thread with pselect
<mq32>
and doing all the async stuff by-hand
<mq32>
and i wondered if i could utilize zig async in this case
<andrewrk>
you should be able to, I think
<mq32>
yeah, maybe
<andrewrk>
as long as there is no suspension point in a function with the C calling convention, it will work just fine
<andrewrk>
(you would get a compile error in that case)
<mq32>
i still have problems grasping the basic functionality of suspend/resume
<mq32>
or let me rephrase
<mq32>
i have understood suspend/resume, but not how async/await interact with these two
<mq32>
maybe you can explain or correct me, i'm trying to tell what i got so far :D
<andrewrk>
to help simplify your intuition about it, you can think of `async` as a "fork" in control flow; one goes into the function, and one skips right past it and keeps going on the next line of code
<andrewrk>
`await` "joins" the forked control flow back together
<mq32>
yeah i got the high end functionality
<mq32>
and how to use it in general code
<mq32>
but i want deep understanding before i start using such a feature
<mq32>
so to my understanding:
<mq32>
async is just a helper that will run the function to the first suspend, will then return to the caller
<mq32>
the suspend will save the current state of all required locals in the frame as well as the instruction pointer
<mq32>
i can later call resume on the frame and the function will continue executing after the suspend
<mq32>
all correct so far?
<andrewrk>
spot on
<mq32>
👍
<mq32>
now i have problems what async does
<mq32>
i know it introduces a suspend point
<mq32>
*await
<mq32>
sorry
<mq32>
so "await foo" will return to the caller of the current function?
<andrewrk>
there are 2 possibilities, and that is one of them
<mq32>
okay. The other possibility would be "the frame is completed and await will return the value of the function"?
<andrewrk>
yes
<andrewrk>
`noasync await foo` asserts that the second possibility occurs, and therefore does not introduce a suspend point
<andrewrk>
the first thing await does is an atomic rmw, putting the awaiter frame pointer on the awaitee's frame, the "who should I resume when I return" field. if the previous value was "I already returned" then it's the 2nd possibility. otherwise, it's the first possibility
<mq32>
hmm
<andrewrk>
likewise, the first thing an async function does when it returns, is an atomic rmw on the "who should I resume when I return" field. if it's a frame pointer, then it resumes (by tail-calling) them. otherwise it returns up the call stack
<mq32>
i think i have to implement a fake-event-loop some day to get a grasp of it
<andrewrk>
here's a small task you can accomplish in 20 minutes and get a grasp of it: make a simple program that lets you run a task in a different thread
<mq32>
tomorrow then :)
<mq32>
right now i'm too tired for that, 0:21 already
<mq32>
should go to bed actually
<mq32>
but thanks for your time :)
<andrewrk>
do it! you'll feel great in the morning
<andrewrk>
good night
<mq32>
sure thing!
<mq32>
and as soon as it makes click on async/await i'll be happy to use it
<fengb>
Heh I’m actually the opposite. Await makes more sense to my silly JS brain and I have to think hard on how to make suspend/resume work >_>
<mq32>
In heart, i'm an assembler coder in disguise :D
<mq32>
I don't want to type assembler, but i want to know what instructions my compiler will emit
dingenskirchen has quit [Remote host closed the connection]
dingenskirchen has joined #zig
<jaredmm>
Is there a way to capture the code that translate-c is failing to translate and output it along with the error?
<andrewrk>
it should at least tell you the source file name and line number so you can look at it
<andrewrk>
I thought we had that hooked up already
mahmudov has quit [Ping timeout: 256 seconds]
marijnfs has quit [Ping timeout: 250 seconds]
mahmudov has joined #zig
<jaredmm>
It does, a bit. I'm getting some output like https://pastebin.com/3mLN7SJf. The line output it gives is inside an inactive preprocessor block (when I'm looking at the headers in Visual Studio).
<jaredmm>
There's also a section of 12 duplicate definitions (just two underscores). `pub const __ = @compileError("unable to translate C expr: unexpected token Id{ .Invalid = void }");`
<jaredmm>
(GetCurrentFiber is also declared twice in the pastebin). At first I assumed there was some weird preprocessor stuff happening.
<jaredmm>
Those bits of code are dealing with unimplemented intrinsics, which I may implement, but I'd like to have it compiling minus the actual syscalls.