Re:Revisiting the design approach to Zig
by tialaramex on Wednesday September 07, 2022 @08:09AM
(#32749538)
I definitely don't miss it while writing my own code. In porting well, I think because we've got volatile flag nonsense, we need to do some significant surgery to even make this compile anyway, and so perhaps
do { ... } while (((data & DAP_Data.transfer.match_mask) != match_value) && match_retry-- && !DAP_TransferAbort);
becomes something like loop {
...
if data & DAP_Data.transfer.match_mask) == match_value {
break;
}
match_retry -= 1;
if match_retry == 0 {
break;
}
if check_transfer_abort() { // Replaces DAP_TransferAbort
break;
}
}
I think that's actually more clear, and my mental focus is DAP_TransferAbort. I think it's just C programmers being C programmers, and we just want AtomicBool for this but I'm more comfortable wrapping it in this check_transfer_abort() function while I investigate whether anybody thinks this is a counter, or there's actually physical hardware backing it despite the way it looks like it's just a global variable.
It has to do with porting code, generally. If I'm writing original Rust, I rarely miss it. It's not a huge deal, but you bump into it juuuust often enough to (probably unfairly) curse Rust out when you hit it yet again.
Here's code from CMSIS DAP debug probe firmware from ARM: https://github.com/ARMmbed/DAPLink/blob/main/source/daplink/...
Note the nested do { do { } while (); if (err) break;} while(); if (err) break;
Should that code be rewritten? Most certainly it should, and it should be given a proper Error type. However, when you are first porting it, you need to match semantics or you get a bunch of off-by-one, missed error, or missed end of stream bugs. And, as you point out, the Rust loop{} equivalents suck.
We've all written suboptimal code, and we all live in a suboptimal world. :)