<mikdusan>
and we have args.append("-D_FORTIFY_SOURCE=2");
<mikdusan>
in my head "release-safe" is defined as all the safety of debug build, without debug info. so yeah, it's odd that release-safe has more safety with glibc than debug
<pixelherodev>
When I try drawing people, it looks like if a stick figure tried drawing a person without ever having met one; it looks like a monk spent countless hours carefully etching a pattern into the paper, only to get sick and undo aeons of effort
dddddd has quit [Ping timeout: 260 seconds]
ur5us has quit [Ping timeout: 260 seconds]
seoushi has quit [Ping timeout: 265 seconds]
seoushi has joined #zig
seoushi has quit [Quit: Leaving]
ur5us has joined #zig
<shakesoda>
pixelherodev: sounds like my old attempts
<shakesoda>
so i spent a few years on it
marmotini_ has joined #zig
marmotini_ has quit [Ping timeout: 272 seconds]
dingenskirchen has quit [Quit: dingenskirchen]
dingenskirchen1 has joined #zig
halbeno_ has quit [Ping timeout: 260 seconds]
dingenskirchen1 is now known as dingenskirchen
halbeno has joined #zig
jjido has joined #zig
jjido has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
return0e_ has joined #zig
marmotini_ has joined #zig
ur5us has quit [Ping timeout: 240 seconds]
<mq32>
hello people
<mq32>
what's the current idiomatic way to pass a std.io.InStream to a function?
marmotini_ has quit [Remote host closed the connection]
dingenskirchen has quit [Quit: dingenskirchen]
dingenskirchen1 has joined #zig
dingenskirchen1 has quit [Client Quit]
dingenskirchen has joined #zig
lunamn_ has quit [Quit: leaving]
marmotini_ has joined #zig
marmotini_ has quit [Remote host closed the connection]
marmotini_ has joined #zig
marmotini_ has quit [Read error: Connection reset by peer]
jjido has joined #zig
phillyiscool has joined #zig
<phillyiscool>
I'm running into various issues trying to create a C library from Zig. A couple of things I need to do:
<phillyiscool>
1. Have functions that accept []u8 (strings)
<phillyiscool>
2. Have functions that returns structs
<phillyiscool>
Both of which gives me "not allowed in function with calling convention 'ccc'" errors...
<betawaffle>
phillyiscool: for 1, i'd suggest two arguments instead. a [*]u8, and a usize
<betawaffle>
and then you can make a slice out of those
<phillyiscool>
So my question is, what *is* allowed with calling convention ccc, and are the types of libraries that deal with structs not able to be built with zig?
<betawaffle>
and for returning structs, maybe it will let you return an extern struct?
<betawaffle>
(which is equivalent to a C struct)
<phillyiscool>
Ah, ok
<betawaffle>
you just have to think about it from the perspective of the C user
<phillyiscool>
Yeah, well i am
<betawaffle>
they only have C-style structs, and they only have pointers and sizes, no slices
<phillyiscool>
From a C user I would expect char pointers
<betawaffle>
you could define a slice-like type, but that wouldn't be idiomatic C
<betawaffle>
right, char pointers *and a size*
<betawaffle>
you could accept a [*:0]u8, but that's not recommended
<betawaffle>
(nul-terminated)
<phillyiscool>
I don't write C functions that require a size when passing a char pointer..
<phillyiscool>
(I'm a bit of a beginner at C so I might be doing things wrong there too)
<betawaffle>
right, so that's called a nul-terminated string. it's common in C, but considered a bad idea generally
<phillyiscool>
If I write a c function like void do_something(char *thing) { ... } is this wrong?
<betawaffle>
because those strings: 1) can't contain any zero bytes, 2) have an unknown length
<betawaffle>
it's very easy to have serious security bugs with an API like that
<phillyiscool>
Hm, I can see what you mean by not having zero bytes
<phillyiscool>
But.. now I'm even more confused as I don't know what I would do with the size if it was given to me
<betawaffle>
basically, you're only supposed to use those when they already exist in an api and can't be changed
<phillyiscool>
So what is the alternative?
<betawaffle>
(in zig) if you have a [*]T and a usize, you can do ptr[0..size] to make a slice
<mq32>
daurnimator: it's crazy how much a single * can make a difference :D
<betawaffle>
phillyiscool: basically the consensus in the C world is that nul-terminated pointers were a mistake in almost all cases, but they are part of some APIs now and can't be removed
<phillyiscool>
Ok, I need to learn about non null terminated strings because I've never seen or used them
<betawaffle>
and just to be clear... string literals (in both C and zig) are still nul-terminated, but they can be used in the _correct_ way if you pass a size along with them (or in zig, which knows the length at comptime)
<phillyiscool>
How do you use them the correct way in C?
<betawaffle>
the short answer is the "size" is literally just the position of the nul (zero) byte in the string, relative to the start
<betawaffle>
well, in C, there's no way to get the length of a string literal at compile time (afaik), but you can use strlen at runtime
LER0ever has joined #zig
<betawaffle>
which iterates over the string (at runtime) looking for the nul byte
<phillyiscool>
What I'm asking is, I have a char pointer and I have a size, what do I do with that size?
<betawaffle>
in zig or C?
<phillyiscool>
In C
<phillyiscool>
I can't program a C lib from Zig until I know how to do it right in C :)
<betawaffle>
ah, right. well the idea is you'd use the size for bounds checking
<betawaffle>
so that you never try to deref a byte beyond what the size indicates
<phillyiscool>
So I'm really just using strings for strcmp()
<betawaffle>
so for example, if you are iterating over the bytes in a string, you'd use i < size in your for loop
<phillyiscool>
I could probably be using enums instead
<betawaffle>
maybe you want strncmp?
<betawaffle>
considered the "safe" version of strcmp
<phillyiscool>
Maybe, I'm not familiar with it
<phillyiscool>
I see that it adds the size
<betawaffle>
that said... it's only "safe" if your n value is correct
<phillyiscool>
Ok, this gives me something to think about
<phillyiscool>
I think since my program is going to have a limited number of strings I should explore enums instead
<phillyiscool>
Adding sizes would make the C api clunky
<betawaffle>
yeah, if all the strings are comptime-known, an enum would be a good fit, probably
<phillyiscool>
And since it's not handling arbitrary strings I would like to avoid that
<phillyiscool>
So I haven't gotten that far, but how does exporting functions deal with comptime, since there is no comptime?
<betawaffle>
an exported function has limitations placed on it's arguments/return value
<betawaffle>
a comptime argument is an example of something that isn't possible (and wouldn't make sense anyway)
<phillyiscool>
Right, but doesn't that mean it also can't *call* into Zig functions that have comptime arguments?
<betawaffle>
correct
<phillyiscool>
In other words, once you use an exported function then your entire library can't use comptime
<betawaffle>
well, no
<betawaffle>
an exported function can call any zig function
<phillyiscool>
Internal things can
<betawaffle>
so your exported api needs to be finite
<phillyiscool>
Right, that makes sense
<phillyiscool>
Well thank you for explaining this all to me, I have a bit to think about
<phillyiscool>
I'm going to play around with using enums and see what that looks like.
jjido has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
jjido has joined #zig
dingenskirchen has quit [Remote host closed the connection]
dingenskirchen has joined #zig
<phillyiscool>
betawaffle I don't think I can use enums because the enum needs to be defined by the C user, not my Zig library.
<phillyiscool>
Which means I would need to use Zig's generics to get the type and I can't use `type` in exported functions.
<betawaffle>
right
<betawaffle>
i thought you meant the strings were known ahead of time by you
<betawaffle>
what's the purpose of this library?
<phillyiscool>
Right, I was thinking of the whole program
<phillyiscool>
It provides a state machine
<phillyiscool>
(the library that is)
<betawaffle>
and why do you need it to export a C api?
<phillyiscool>
Because almost all embedded programming is in C
<betawaffle>
so you're making something that an existing embedded program written in C will use?
<phillyiscool>
No, it's that I don't necessarily get to decide what language will be used so I want to have both a C and Zig version
<betawaffle>
hmm
<phillyiscool>
If I have the choice I'll definitely choose Zig
<betawaffle>
keep in mind that zig is not production-ready
<phillyiscool>
So it might just be that I need to make both a Zig and C version separately, which is fine.
<betawaffle>
(yet)
<phillyiscool>
Yeah, that's true too
mokafolio has quit [Read error: Connection reset by peer]
phillyiscool has quit [Remote host closed the connection]
phillyiscool has joined #zig
dingenskirchen has quit [Quit: dingenskirchen]
dingenskirchen1 has joined #zig
dingenskirchen1 is now known as dingenskirchen
phillyiscool has quit [Remote host closed the connection]
marmotin_ has joined #zig
jjido has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
marmotin_ has quit [Ping timeout: 240 seconds]
marmotini_ has joined #zig
marmotini_ has quit [Read error: Connection reset by peer]
dddddd has joined #zig
dingenskirchen has quit [Remote host closed the connection]
dingenskirchen has joined #zig
<fengb>
Is this a clever use of defer or lazy overengineering? `defer self.cur = 0; return self.out[0..self.cur];`
<BaroqueLarouche>
a mix of both ?
<fengb>
lol... the defer version is actually slightly faster in debug mode
<betawaffle>
how much slightly?
<betawaffle>
fengb: seems legit given result location semantics
<shakesoda>
it smells a bit of trying to be too clever but makes sense
<betawaffle>
i mean, the alternative would be two extra lines
<betawaffle>
well, to be fair, debug mode is *really dumb* from an instructions-generated standpoint
<betawaffle>
lots of stack spilling, etc
<betawaffle>
they are both exactly the same in release-safe
LER0ever has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
metaleap has joined #zig
<fengb>
I expected defer to be a little screwy
<betawaffle>
it has very clear semantics
<metaleap>
betawaffle, question about the clear semantics of defer: is there any difference between `if (b) { defer d(); }` and `if (b) defer d();`?
<betawaffle>
heh
<metaleap>
not sure if "block"/"scope" in zig only really "truly does exist" with braces, or even in the braceless case above up there.
waleee-cl has joined #zig
<betawaffle>
well, for that answer think about if (b) const foo = 5;
<betawaffle>
that would be nonsensical
<betawaffle>
so my answer is no, they are the same
<betawaffle>
(if they aren't, that seems like a bug)
<metaleap>
ah, so any conditional defer must be stated unconditionally: defer if (b) d();
<betawaffle>
right
<betawaffle>
there are no such thing as conditional defers in zig, afaik
<metaleap>
somehow that possibility eluded me late last night :D
<betawaffle>
metaleap: worth noting though the time that b gets evaluated is different
<metaleap>
sure
<metaleap>
in doubt one would have to capture the state at the time of deferring
<betawaffle>
yep
<fengb>
"Since JavaScript doesn't supports int64 yet, a signature with a int64 in wasm can't be exported to JS." wtf
<fengb>
Sigh
<fengb>
RIP safari support I guess :P
_Vi has joined #zig
<mq32>
metaleap: if (b) defer d();
<mq32>
i don't think that is valid syntax as defer isn't a expression
<mq32>
but: not sure
<metaleap>
you're right
zfoo_ has quit [Remote host closed the connection]
dingenskirchen has quit [Quit: dingenskirchen]
dingenskirchen1 has joined #zig
dingenskirchen1 is now known as dingenskirchen
Akuli has joined #zig
marmotini_ has joined #zig
marmotini_ has quit [Remote host closed the connection]
<frmdstryr>
Is there any way to save a generic pointer then restore it back? I'm trying to support callbacks to a "bound fn" by saving the owner and fn then invoke it later
<frmdstryr>
Ideally without needing to change the fn proto of the fn to use usize instead of *Self
<SyrupThinker>
frmdstryr: If it is compile time known you can try var as the parameter type
<frmdstryr>
Will that work with different "owner" types?
<frmdstryr>
Is what I have, is there any cleaner way to do that?
<frmdstryr>
Ideally I'd somehow cast the addr back to the proper type in invoke
<frmdstryr>
so each callback doesn't have to do it
<fengb>
var is comptime only so you can't really do that dynamically
adamkowalski has joined #zig
<fengb>
There needs to some design around how to represent that at the machine
<fengb>
A function call is basically, "push variables on the stack, jump to the instruction location"
<fengb>
To make that runtime generic, you need to standardize the stack variables
<frmdstryr>
Can a type be saved in a variable?
<frmdstryr>
@ptrCast(self.type, addr)
<fengb>
No
<betawaffle>
types have zero size at runtime
<fengb>
Possible generic signature (C syntax): `invoke(ctx: *void, args: *void)`
<metaleap>
frmdstryr: my recent callback solution looks to the userland like L69 / L78 / L84 in https://github.com/meta-leap/jsonic/blob/master/demo.zig#L69 --- if that sort of approach would fit your needs, you can easily see how its done in src/jsonrpc_engine.zig searching for all references to ResponseAwaiter and handlers_responses. but might be too naive wrt your reqs
FireFox317 has joined #zig
<metaleap>
alas however i know (and you might not) the "context arg" SizeOf because it is all derived from a (userland-defined) union of "method" signatures
<fengb>
I don't think we have a common solution for runtime callbacks yet. Best we have are interfaces, like Allocator
<fengb>
I think doing callbacks "right" would basically be the same solution as closures
<betawaffle>
would Allocator have been designed differently if @hasDecl and such existed at the time?
<frmdstryr>
@metaleap the problem with that is it only supports one Owner type
<metaleap>
you mean my "State" arg?
<frmdstryr>
I was looking at the Engine
<metaleap>
i support any + void. just not var. yeah ok for "overloads"/runtime-type-switching-without-predefined-unions i have no solution at hand =)
<SyrupThinker>
fengb: Something like D's delegates?
<metaleap>
ah there that "Owner" is just whatever type of "instance" to be passed back out to onOutput, nothing to do with the callbacks
<fengb>
I don't know anything about D >_>
<SyrupThinker>
Its basically a function with context as a type
<frmdstryr>
^^ yes
<fengb>
Lemme see if I can hack something together
adamkowalski has quit [Remote host closed the connection]
marmotini_ has joined #zig
qazo has quit [Read error: Connection reset by peer]
<fengb>
So in theory, you can pass &closure and &closure.call into C and it'll rip out the binded args
<frmdstryr>
Anon structs make zig hard to read...
<fengb>
It doesn't help that I have nested anon structs :P
<mq32>
frmdstryr, it depends on the topic
<fengb>
This can probably be rewritten to be less confusing
<frmdstryr>
Haha yeah, I'd say it's still easier to read than the c++ Callback code
<frmdstryr>
Calling Contex.bind is generating a new type correct?
<fengb>
I'm already lost in my own code
<fengb>
Ah, Closure.bind creates a new struct that glues together the args and the function pointer
<fengb>
After looking at it... we don't need any of this @fieldParentPtr shenanigans. We can simply create a void pointer
<frmdstryr>
I think the magic there is the parentFieldPtr is allowing you to use the nested closure.call to grab a ref to the original ctx
<fengb>
Yeah but I don't think that's needed
<fengb>
It's following the existing interface style, but we don't need that if we only have 1 function and 1 datapoint
<fengb>
That only really requires func(*args)
<fengb>
I need to get back to my day job lol
<frmdstryr>
me too, ha, already blew off the whole morning
<frmdstryr>
is *any the same as a void ptr?
<fengb>
Yeah basically. I could call it *c_void if it feels better
<frmdstryr>
I don't see that anywhere in the docs... is that new or something?
<fengb>
No, just a convention I made up, like everything else here `const any = @OpaqueType();`
<fengb>
I think someone in here recommended using opaque as an any
<frmdstryr>
"void is distinct from c_void, which is defined like this: pub const c_void = @OpaqueType("
metaleap has joined #zig
<SyrupThinker>
I spoke in favor of that over *u8
frmdstryr has quit [Ping timeout: 240 seconds]
pmwhite has joined #zig
<pmwhite>
Is there a Zig xml library
ur5us has joined #zig
<metaleap>
fengb: "This... is not pretty" actually from just the userland perspective it's pretty nifty! i think this can be quite handy. also thx to ur snippet I learned about `*const @OpaqueType()` for any-pointers, believe it or not I clumsily used to ptr2int / int2ptr for that usecase!
<metaleap>
the @call with args-tuple thing is also a swell pattern to remember
jjido has joined #zig
<fengb>
Yeah I almost said it can't work before I remembered we added @call :P
frmdstryr has joined #zig
<fengb>
I think I have a much better solution but I can't get it done right now
<metaleap>
if one wanted to go wild one could even attempt to hack partial-args in there. ie. supply only *some* args with the possibility to pass missing ones to call() :D
<andrewrk>
what's the goal here? we have a pattern used by std.fmt.format and std.Thread.spawn which takes `context: var`
<andrewrk>
oh I see
<andrewrk>
that looks very lispy
frmdstryr has quit [Ping timeout: 240 seconds]
<andrewrk>
I see, the goal is to have a runtime array of thingies
<fengb>
frmdstryr was asking about runtime callbacks. I had something that was horribly slapped together earlier. This is my cleanup... which may not be any better
<fengb>
But this would theoretically support any callback by passing in `fn(*void) ReturnType, *args`
<fengb>
Only in theory. I haven't tried exporting it to C or anything :P
frmdstryr has joined #zig
<betawaffle>
andrewrk: it's not friday yet
<andrewrk>
eh, I overestimated the return ETA
<betawaffle>
have you made any more progress on the game since the end of the stream?
<andrewrk>
nope
frmdstryr has quit [Read error: Connection reset by peer]
jjido has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
jjido has joined #zig
marmotini_ has quit [Remote host closed the connection]
<andrewrk>
mikdusan, the "out of memory" errors happening on freebsd sr.ht seems to be happening for all the @cImport tests. I'm about to try a simple hello_world.c
<daurnimator>
mq32: oh were you talking about #4446 ?
ur5us has quit [Ping timeout: 245 seconds]
<mq32>
yep :)
<andrewrk>
mikdusan, sourcehut does not support giving access to builds, so the closest thing available if you want to troubleshoot is to manually submit a manifest (that matches somewhat close what zig submits) at https://builds.sr.ht/submit under your account, then you should be able to reproduce the issue