|
|
Log in / Subscribe / Register

DeVault: Announcing the Hare programming language

DeVault: Announcing the Hare programming language

Posted May 2, 2022 20:14 UTC (Mon) by mathstuf (subscriber, #69389)
In reply to: DeVault: Announcing the Hare programming language by NYKevin
Parent article: DeVault: Announcing the Hare programming language

> Let me be less flippant and more explicit

Thanks :) .

> In a sane world, I'd be able to just say "well, I don't care about targeting any of those weird platforms; if you want to support them, you're on your own."

I agree that some kind of:

std::static_assert(std::target::is_twos_complement()); // definitely required
std::warn_on(!std::target::os::any_of(std::target::os::macos, std::target::os::linux)); // Windows is untested, but allow tinkering

support would be wonderful. But that's missing and is currently only metadata.

> But I can't say that, because compiler writers have decided that UB means "the compiler twists your code into a pretzel."

The twos complement example gets used all the time, but I heard another tale of why signed overflow is undefined: type promotion. If I iterate over a `short` and overflow is important, promoting to an int to access faster instructions or whatever and just letting it overflow to `USHORT_MAX+1` is no longer a valid optimization. C type promotion is weird and the differences between signed and unsigned promotions are likely reasons why one has defined extrema behaviors, but I don't know that much about that side of it. I admit that my grokking of the relevant rules is fuzzy at best and compiler warning-guided at worst.

Rust's `Wrapping` and `Saturating`types make this far better by making such assumptions explicit. The debug check vs. release free-for-all is an acknowledgement that such behavior is fine in most cases, but should be considered. Those that want specific assumptions recognized should really tell the compiler about them. But Rust has ways of doing so and C and C++ still lack it.

> I understand that some of these optimizations do improve performance in various ways, but they also result in things like optimizing out NULL checks if you can prove that the pointer was previously dereferenced (a problem which has struck the kernel more than once, as I recall).

Yes. I'd love the compiler to signal "hey, I made UB-assumptions", but that is apparently very non-trivial in practice. At least with current compiler architectures. Maybe someone will implement better origin tracking when working on LLVM bytecode or GCC's GIMPLE to "see" what was actually written, but I don't see new C++ compiler infrastructure getting anywhere in the next 5 years seeing how many have "given up" and migrated to being LLVM/Clang reskins (though many were EDG skins, this consolidation is not promising IMO). I suspect the prevalence of macro-stamped code and optimizing inline code makes this difficult because you *want* such optimizations in those cases. Template instantiation almost certainly has similar problems.

Additionally, Ralf Jung's blogs[1] on[2] provenance[3] show that there are ways that different passes, while fine on their own, may *combine* to abuse UB into something unintended (though this is more about showing that provenance has to be a thing than UB in general, I would be surprised if there were no cases of such behaviors between various dead code and value analysis optimization passes). I have no idea how that is expected to be tracked and handled internally.

[1] https://www.ralfj.de/blog/2018/07/24/pointers-and-bytes.html
[2] https://www.ralfj.de/blog/2020/12/14/provenance.html
[3] https://www.ralfj.de/blog/2022/04/11/provenance-exposed.html


to post comments


Copyright © 2026, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds