by gingerBill | 2025-09-06 12:15:17+00:00
Sorry to pop in but I kind of need to clarify my own position even further here:

Odin has "undefined behaviour". SHOCK! HORROR!

The thing I bring up that people think I go "ad nauseum" about (like yourself) is just that the term "undefined behaviour" is in itself "undefined". This is why I try to make as many distinctions about the different kinds of "UB" out there, and even what the "U" means in "UB".

To quote you from earlier:

> ...Ginger Bill will engage in pointless semantic arguments in which he defines away your problem.

Yes... the entire discussion about "UB" is fundamentally a semantic thing, LITERALLY it's an argument about semantics. And if I can "define away [the] problem" in certain cases, then it's literally not Undefined Behaviour. I am not sure what else to say to your point here. The entire discussion around UB is fundamentally a semantics game and always will be. And when people complain about the "semantics game" part, they have not understood the problem in the first place.

Interestingly, the C++26 example you give is a brilliant example of this, it's an Erroneous Behaviour, not necessarily "undefined" or "unspecified".

In the case of race conditions in Odin? This is pretty much a brilliant example of _Unobservable_ behaviour because Odin shares a similar memory model to C, and thus it has to make assumptions. And when the programmer violates certain assumptions, the compiler cannot observe the broken code that easily, and thus it can easily produce unexpected behaviour due to it being unobservable.

I know have said things in passing, but it's a question of what to tell people. A lot of the people who bring up examples of UB bring up are usually TRIVIALLY definable, and things we have probably already defined in Odin (e.g. integer (under|over)flowing, integer division by zero, etc), but when I say what Odin's defined it to, they usually go one of two ways, either "I don't like that definition" or "but I wanted to use these specific passes in the compiler backed to do 'optimizations' with", both of which actually annoys me because I am not discussing with someone serious. In the latter case, "passes" are just algorithms that do things; they are not intrinsically "optimizations". To "optimize" something, you need well defined rules to optimize within, if the rules are ill-defined or arbitrary chosen, then how the heck can anyone call that "optimization"?

> In a language with UB, the use after free is UB. Which explains the nonsensical results. [https://odin.godbolt.org/z/8onn4hxP1]

Even the case of "use after free" that you brought up earlier, it is something which is not a language thing in certain cases, especially when Odin has custom allocators which are defined at the user-level. The language itself knows nothing about of the allocators and how they work, it cannot. So yes, Odin allows for "use after free" but and? We are not enforcing a specific memory allocation strategy at the language level, like other languages. But it could be technically well defined at the algorithm level of that specific allocator. Which leads to my many problem with this discussion: are flawed algorithms/code considered Undefined Behaviour now and thus make the language "UB"? Why is not just shitty code?

And I will literally go... your "nonsensical results" are just... allocator specific behaviour. Yes it's "nonsensical" to you, but Odin isn't C so stop applying its approach to things to it. C has its standard library as part of its spec and defines how `malloc` et al work. Odin doesn't have its core library as part of the spec and never will (base library will to a certain extent with room for implementation specified behaviour for certain defaults, e.g. what is the default `context.allocator` or `context.assertion_failure_proc`, etc).

> Bill's go-to is to blame somebody else...

No... my go-to response is to say where it should be defined, and if it is possible to define at _any_ level (if at all). So even in your case, you are blaming the compiler for something it cannot know if this is undefined or erroneous because it cannot know what you are doing, but the allocator itself could allow for it. `delete` could be a complete no-op and is for many allocators.

It's all about responsibility. What is responsible for what. So if you thin that's "blame", whatever, but that's the question. Is the compiler _responsible_ for "use-after-free" bugs? In some languages, yes. In other languages, no.

> Linux didn't define your programming language, Intel didn't define your programming language, this is your fault Bill.

No but they all put bounds on what is possible in the first place. They literally define the arena the language takes place in, and thus you are subject to their whims, regardless of my feelings about them. No it's not "my fault" anywhere, it's just a thing.

----------

If you want to discuss with me further on this, I'd be happy to do so. Other mediums other than a comment on Hacker News would be preferrable.

----------

P.S. nowhere on the Odin website itself do we say Odin has no "UB" nor even suggest it. So there is no official position on "UB" for Odin anywhere. My comments on Twitter or other social medias should not be taken as official in any way, and be considered closer to "conversation", especially Twitter.

P.P.S. Some of possible meanings of "U": Undefined (i.e. not-defined), Undefinable, Unspecified, Underspecified, Unobservable, Unknown, Erroneous (I know it's not a U), Unimplemented, Ill-Defined (different to Undefined or Underspecified, and again not a U), Defined-At-A-Different-Level (e.g. language, compiler, platform, core library, user's code, etc, and again it's not a U). It's an absolutely mess and things just need to be defined better about what you are talking about.