<betawaffle>
heh, if only the whole industry supported the "industry standards"
<metaleap>
andrewrk: on zig/ast.Location is the `column` a byte-offset-based count or utf-8-based / "editor-like" (aka every char >127 still represents 1 column)?
<metaleap>
(and every multibyte "char"/rune too)
<andrewrk>
column is bytes
<metaleap>
andrewrk thx
<andrewrk>
note that zig has line-independent tokenization
<andrewrk>
so an editor will only have to be unicode-aware starting from column 0 of that line
<andrewrk>
also if there are no string literals or @"identifiers" on a line, it's currently guaranteed to be ascii
<Xatenev>
any possibility to call `zig build-exe` with the executable name? cant find it
<andrewrk>
are you looking for `--name` ?
<metaleap>
andrewrk understood, i already found the std.unicode.utf8* stuff so should be able to reconstruct editor-position-info from `Location` and vice-versa
<Xatenev>
andrewrk: oh my bad, thanks! i found it now in the compile options too :)
<Xatenev>
that was it.
<Xatenev>
one thing I wonder, im experimenting a bit with `comptime` - when I have a basic function fn add(x: i64, y: i64) i64 { return x + y; } and then call it via comptime: const len = comptime add(1,2); const arr: [len]u8 = undefined;
<Xatenev>
that works fine with comptime, but without comptime it doesn't
<Xatenev>
"expected type "usize", found "i64"
<Xatenev>
where can i read about more info on that behavior?
<andrewrk>
Xatenev, I think the docs could be improved with the rules of when automatic type coercion is allowed. but the rule you're looking at right now is - if an integer is comptime-known, then it will allow an automatic coercion to another integer if it fits into the destination type
<Xatenev>
i see, that makes sense
<andrewrk>
otherwise if it's runtime-known, then it has to use the types alone to decide if it's a safe conversion
jjido has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
riba has joined #zig
LER0ever has joined #zig
LER0ever has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<andrewrk>
colorless functions are real! this function LibCInstallation.findNative is compiled in blocking I/O mode when it is used from the stage1 compiler, but it's compiled with async I/O when used from stage2
<andrewrk>
that pattern works in function-local scope, and it *should* work in global scope but there is a bug
<mq32>
which i've seen quite often in the std library, but i was scared that it will break
<mq32>
my thought was: it will only keep the ".stream" object, but not the actual SomethingStream=struct{…,stream:IOStream(…)}
<mq32>
so yes, the behaviour is "safe" in terms of accessing stream later, but will maybe? break when calling @fieldParentPtr
<fengb>
Having escape analysis could locate most of these errors
<jessermeyer>
Yes, it does.
<jessermeyer>
Winerror.h just casts the signed bit away.
<andrewrk>
jessermeyer, I don't have enough information to advise you. This isn't really a Zig question. It's a question of what you want your bits in memory to be. Zig lets you make your bits whatever you want them to be
decentpenguin has quit [Quit: decentpenguin]
<jessermeyer>
So if these bits are produced and interpreted by a chain of black boxes, how do I continue to use Zig here?
<jessermeyer>
It's actually a very simple task I'm wanting to do.
<jessermeyer>
FunctionA might return an error, and its value is a HRESULT, which is a c_long, but its error code is designated as a UL, and its range, _as specified_ exceeds the c_long.
<jessermeyer>
That value can then be fed into another function to tell me more information about what failure occurred.
<jessermeyer>
I mean, it's a totally insane API.
<mq32>
UL is unsigned long, you could bitcast those types
<jessermeyer>
Ah, the bitcast ...
<jessermeyer>
Here's the hilarity. Consider 0x887A0002L. That is how the error code is specified. That hex value exceeds the L range. If I 'expand' that number in VS, it automatically converts the L to UL.
<andrewrk>
it sounds like you want @bitCast
<jessermeyer>
Yeah
<jessermeyer>
So, translate-c has no hedge against this, I imagine.
<jessermeyer>
I'll open a ticket for discussion.
<andrewrk>
so far it doesn't sound like a zig issue
<jessermeyer>
It's a fuzzy boundary. Every Zig programmer interfacing with winerror.h will have to face this, especially if it comes through translate-c. The Zig generated code produced by translate-c _does not compile_ cleanly.
<jessermeyer>
In fact, it doesn't even compile at all. Not without this @bitcast
<andrewrk>
ok that sounds like a zig issue. thanks
<andrewrk>
Dominic[m], check the man pages for write - it explains when EINVAL occurs
<Dominic[m]>
I had a look, but the case doesn't make much sense to me! https://linux.die.net/man/2/write How can fd be attached to an object unsuitable for writing, if the file is being written to?
<Dominic[m]>
Unless zig is sending O_DIRECT, but I didn't (intentionally) ask it to do that
<andrewrk>
nah zig isn't adding O_DIRECT
<andrewrk>
maybe an strace would be informative
<Dominic[m]>
Oh, I see. strace is awesome.
<Dominic[m]>
So, what happened is that I'm writing to "/sys/class/backlight/intel_backlight/brightness", and I was copying how most scripts write to it `echo "123" > /sys..`, including the trailing newline. But that causes an EINVAL when writing the newline. In C/bash/everything else, this just silently works!
<Dominic[m]>
oh, Java also silently ignores this.
<jessermeyer>
Nice find!
<Dominic[m]>
As an aside, is there a simple way to do (u8*u8)/100? There's a potential overflow in the middle, but doing the /100 first causes problems with rounding :)
<TheLemonMan>
uh this is weird, stracing `echo` shows that write doesn't return any error
<TheLemonMan>
can you share your Zig code?
<Dominic[m]>
Yeah, I just tried my C code and noticed the same!
<fengb>
How about extend the u8 into u16 first? That should be a “noop” in most architectures
<TheLemonMan>
oh here's what happens, the formatter is printing the integer argument first (the {} part) and then the newline
<TheLemonMan>
sysfs doesn't like that and returns an error
<andrewrk>
it wants the entire write to happen atomically
_Vi has quit [Ping timeout: 272 seconds]
<andrewrk>
leaving off the \n seems like a good solution
<andrewrk>
assuming the \n is superfluous
<Dominic[m]>
It is superfluous, yeah.
<TheLemonMan>
I guess the kernel is only interested in the numerical value
<Dominic[m]>
Are there any cases where splitting the writes might be bad? Perhaps with misbehaving fuse devices?
<andrewrk>
it's probably calling atoi or whatever libc function which will give a value even if there is junk after the integer
<TheLemonMan>
split writes are bad when the underlying device is not a normal file
<TheLemonMan>
if the outStream were a buffering one you wouldn't notice this problem :)
<andrewrk>
well you would if the packet was big enough
<andrewrk>
in this case a buffer is one of those things that mostly makes things work but then creates a really annoying leaky abstraction
<andrewrk>
IMO better for the API user to manage a buffer if the system wants certain packets
<Dominic[m]>
I've avoided a buffer because I'm (for no real purpose than to try) optimizing all the things.
<TheLemonMan>
indeed, a buffered stream adds one more layer to manage
<andrewrk>
right, in that case zig's lack of buffering is helping you because if you do introduce a buffer, that's the only layer
FireFox317 has quit [Ping timeout: 240 seconds]
<Dominic[m]>
For whatever reason, zig runs 1ms quicker than the C version, consistently. Yay zig :) It also highlights way more error points than the C one did.
jessermeyer has quit [Remote host closed the connection]
<Dominic[m]>
Possibly not a question for this channel. But I'm comparing the output of strace from the C & zig version to get a feel for the timings. It looks like the C version uses malloc to allocate arguments, I noticed a comment in one of the argument examples where it mentioned the slow C allocator. It seems that in this case, zig is somehow able to avoid that altogether. I am using nextPosix() to achieve that. Does gcc not follow
<Dominic[m]>
that behavior on posix platforms?
<Dominic[m]>
I guess I'm assuming that's why brk() is being called, and I don't know that's why. Silly assumption.
<andrewrk>
Dominic[m], you're asking about the command line arguments?
<andrewrk>
when linux begins executing a binary, it has the command line arguments in stack memory. zig leaves them there and refers to them directly
<Dominic[m]>
andrewrk: I think so. Does C/gcc use malloc to allocate the cli argument?
<andrewrk>
however, usually there will be a heap allocation when writing cross platform software, because on windows it is necessary to convert to UTF-8
<andrewrk>
if you're comparing with C then I'm guessing you're observing the dynamic linker do a lot of stuff
<andrewrk>
you can make it leaner by using zig to build a simple C file statically with musl
<andrewrk>
with this proposal it would be: @intCast(u8, math.mul(a, b) / 100)
<Dominic[m]>
Ooh, that would be handy. Subscribing!
<Dominic[m]>
Thanks.
mahmudov has joined #zig
<mq32>
andrewrk: that's a nice idea!
<mq32>
so when i want to have truncating multiplication, i can just @truncate(u8, std.math.mul(a,b)) or use cast for overflow detection :)
<mq32>
neat!
<Dominic[m]>
Has anyone played around with using zig in conjunction with a RTOS?
<andrewrk>
yes idea is that you can do a bunch of math with ever-increasing integer bit sizes (but they are inferred) and then at the end you decide whether you want to assert no overflow, detect overflow, or something else
<pmwhite>
What are efficiency considerations? Do you think it will just optimize into the same thing?
<mq32>
pmwhite, yeah probably
<fengb>
But wouldn’t that differ from .add and .sub?
<mq32>
C does this all the time
<andrewrk>
it depends on how large the types grow. if you do too many multiplications you will quickly end up with very large integer types, in which case it would have been better off to handle overflow earlier
<mq32>
if you add two uint8_t in C, they will widen to "int", add, then will be clamped again into uint8_t
<andrewrk>
with add and sub it would work fairly well, because if you start with a relatively low number like u8, you could do something like 48 additions before getting an integer larger than u64
<andrewrk>
in machine code that's just a bunch of register math
<TheLemonMan>
I'd be wary of the code duplication
<andrewrk>
how so?
<TheLemonMan>
you end up with an endless set of `mul` for different input/output types
<fengb>
mq32: C overflow is undefined. Most implementations wrap but that depends on the compiler :P
<mq32>
fengb: yes. overflow is undefined for signed types
<mq32>
but!
<mq32>
it is defined that types widen suddely :D
<andrewrk>
TheLemonMan, in theory they would all be inlined. but I agree, it is appropriate to be wary of this
Xatenev has quit [Quit: Leaving.]
<andrewrk>
oh nice, the wine package on my system is upgraded to 5.0 and now the cross compiled zig std lib tests pass again
jjido has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<jessermeyer>
^_^
dbandstra has joined #zig
TheLemonMan has quit [Quit: "It's now safe to turn off your computer."]
jjido has joined #zig
<Flaminator>
Is there an easy way to extract 10-bit values from an array of u8?
<andrewrk>
I believe PackedIntArray from the std lib handles this use case
<Flaminator>
I am currently doing something like http://aeug.eu/p/5a52.jpg but that seems rather cumbersome.
jessermeyer has quit [Remote host closed the connection]
jjido has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<andrewrk>
they want to put a "guard page" after the stack, so that if the memory is accessed, it causes a segfault
<andrewrk>
that's how stack overflow mitigation works in most languages, including zig currently
<fengb>
Oh is this “cheaper at runtime” compared to bounds checking?
<andrewrk>
yes, the segfault is triggered in hardware, so it's basically free
<fengb>
But specifically to wasm, there are better solutions, unless it’s using the native stack as the wasm stack
<andrewrk>
but it requires "probing" the stack for functions with frames larger than the page size
metaleap has quit [Quit: Leaving]
<fengb>
I guess I should just implement the naive way and “discover” the better solution :P
<andrewrk>
once zig has safe recursion, stack-annotated function pointers, and ability to measure stack upper bound size at compile time, it will become the only language that has all of these at the same time: (1) prevention of stack overflow (2) no bounds checking (3) no stack probing or guard pages (4) no hidden memory allocations
<fengb>
I meant specifically for the wasm vm, it feels weird to let it page fault, since I think I can code the vm path to have no dynamic stack requirement
<fengb>
But I suppose it makes sense if it’s cheaper than bound checking every stack push inside the VM
<fengb>
Just trying to figure out what the hell I’m doing >_>
<andrewrk>
if perf isn't the main goal of the vm, I think avoiding signals entirely is a cleaner design
<andrewrk>
even if it is, some kind of JIT + smart bounds checking might still be the best bet
<jaredmm>
What is the correct way to cast 4 bytes from an offset in a []u8 to a u32?
<andrewrk>
one of the std.mem.readInt functions
<andrewrk>
depending on whether you want native, little, or big endian
<fengb>
Okay that makes sense. Using signals reminds me of exceptions heh
<andrewrk>
one big problem of signals is that they are very global. relying on signals in a library is very problematic, for example
<andrewrk>
and maybe somebody wants to embed the wasm vm in another project