3 ms·
I'm sure there have been attempts at defining a language that has no UB, but afaik all meaningful languages have UB in some dark corner or enumerated explicitly
by repelsteeltje 5mo ago
I'm sure there have been attempts at defining a language that has no UB, but afaik all meaningful languages have UB in some dark corner or enumerated explicitly. For example, Java thread execution order is UB.
- aw1621107 5mo ago> For example, Java thread execution order is UB. In this context "UB" means something different than how you're using it. The UB being mentioned here is the "nasal demons" form, i.e., programs which contain undefined behavior have no defined meaning according to the language semantics. What you're talking about is probably better described in this context as "unspecified behavior", which is behavior that the language standard does not mandate but does not render programs meaningless. For example, IIRC in C++ the order in which g(), h(), and i() are evaluated in f(g(), h(), and i()) is unspecified - an implementation can pick any order, and the order doesn't have to be consistent, but no matter the order the program is valid (approximately speaking).
- repelsteeltje 5mo agoGreat example. So this "unspecified behavior" might turn into the more nasal demon type when g(), h() and i() share mutable state and assume some particular sequential order of execution. No?
- aw1621107 5mo agoNot necessarily. Unspecified behavior and undefined behavior are independent concepts; a language can have one but not the other. As a result, you can have languages where incorrect reliance on unspecified behavior can lead to undefined behavior (e.g., C and C++) and languages where incorrect reliance on unspecified behavior can lead to bugs, but not nasal demons (e.g., Java)
- fc417fc802 5mo agoThat would depend entirely on the assumptions being made and the constructs being used. I think in most cases it would likely just result in regular garden variety bugs. But sure, if you're writing C++ and (for example) g is depended on for initialization of pointed memory that the other two consume you could end up with UB. But if you're writing Java then no, you will not end up with UB just buggy code.
- tialaramex 5mo agoIt's not difficult to have a Special Purpose language with no UB. There isn't any UB in WUFFS (a language for Wrangling Untrusted File Formats Safely) for example. Those "dark corners" come into the picture when you decide you want a General Purpose language. When your program might actually intend to respond to emails by executing the x86-64 machine code squirrelled away inside this logo PNG and running the output as SQL on your customer database, it's not possible for the language to ensure that programs which weren't intended to do that can't do that, how would they know? The translator isn't a mind reader, your intent is unreadable. I think we should use general purpose languages much less often, the industry doesn't seem to agree, the results are obvious for everyone to see. Rust has a subset, "safe Rust" which isn't a fully general purpose language but deliberately shares its syntax with a larger unsafe Rust you can use when it turns out that you needed it. Safe Rust doesn't have UB.