10 ms·
Code written below your line gets executed if you don't return early. More breaking news at 8. Seriously, why would you think that assigning a value would stop
by merdaverse 1y ago
Code written below your line gets executed if you don't return early. More breaking news at 8.
Seriously, why would you think that assigning a value would stop your script from executing? Maybe the Typescript example is missing some context, but it seems like such a weird case to present as a "data race".
- love2read 1y agoIt seems weird to shame someone for talking about their own experience?
- lights0123 1y agoexit(), execve(), and friends do immediately stop execution—I could understand why you'd think a redirect would as well.
- JoshTriplett 1y agoExactly. Given that JavaScript runs in the context of a page, redirecting off of the page seems like it should act like a "noreturn" function...but it doesn't. That seems like a very easy mistake to make.
- dvt 1y agoThe redirect is an assignment. In no language has a variable assignment ever stopped execution.
- dminik 1y agoThat doesn't seem that obvious to me. You could have a setter that just calls exit and terminates the whole program.
- dvt 1y agoYeah, this is actually a good point, could have a custom setter theoretically that simply looks like assignment, but does some fancy logic. const location = { set current(where) { if (where == "boom") { throw new Error("Uh oh"); // Control flow breaks here } } }; location.current = "boom" // exits control flow, though it looks like assignment, JS is dumb lol
- JoshTriplett 1y ago$ python3 Python 3.13.7 (main, Aug 20 2025, 22:17:40) [GCC 14.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> class MagicRedirect: ... def __setattr__(self, name, value): ... if name == "href": ... print(f"Redirecting to {value}") ... exit() ... >>> location = MagicRedirect() >>> location.href = "https://example.org/" Redirecting to https://example.org/ $
- dvt 1y agoYou're overloading a setter here. It's cute, I did it in JS as well, but I don't really think it's a counterexample. It would be odd to consider this the norm (per the thought process of the original blog post).
- rowanG077 1y agoThis is not some weird thing. Here is a run of the mill example where python can have properties settting do anything at all. And it's designed like that. import sys class Foo: @property def bar(self): return 10 @bar.setter def bar(self, value): print("bye") sys.exit() foo = Foo() foo.bar = 10 Or in C# if you disqualify dynamic languages: using System; class Foo { public int Bar { get { return 10; } set { Console.WriteLine("bye."); Environment.Exit(0); } } } class Program { static void Main() { Foo obj = new Foo(); obj.Bar = 10; } } This is not some esoteric thing in a lot of programming languages.
- dvt 1y agoYou're also overriding a setter. Maybe I'm going against the grain here, but it's absolutely esoteric. The assignment operator is not supposed to have side-effects, and maybe this is the logician in me, but the implication that we should be aware that weird stuff might be happening when we do `x = 5` is fundamentally bonkers.
- lock1 1y agoYou could overload operator=() in C++ with a call to exit(), which fulfills "variable assignment that halts the program".
- dvt 1y agoI was ignoring these kinds of fancy overload cases, but even in JS you can mess with setters to get some unexpected behavior (code below).
- BobbyJo 1y agoidk if I'd consider overloading the assignment operator to call a function, then using it, actually an assignment in truth.
- eru 1y agoWell, when you read the source of the caller, it looks exactly like a normal assignment.
- pjmlp 1y agoAnd for a Rust contrived example, making += terminate execution, use std::ops::AddAssign; use std::process; #[derive(Debug, Copy, Clone, PartialEq)] struct Point { x: i32, y: i32, } impl AddAssign for Point { fn add_assign(&mut self, other: Self) { *self = Self { x: self.x + other.x, y: self.y + other.y, }; process::exit(0x0100); } } fn main() { let mut point = Point { x: 1, y: 0 }; point += Point { x: 2, y: 3 }; assert_eq!(point, Point { x: 3, y: 3 }); }
- ordu 1y agoTry this in C: *(int*)0 = 0; Modern C compilers could require you to complicate this enough to confuse them, because their approach to UB is weird, if they saw an UB they could do anything. But in olden days such an assignment led consistently to SIGSEGV and a program termination.
- DannyBee 1y agoUnless you were on systems that mapped address 0 to a writable but always zero value so they could do load and store speculation without worry. IBM did this for a long time
- deleted 1y ago[deleted]
- mabster 1y agoMy favourite were older embedded systems where 0 was an address you actually do interact with. So for some portion of the code you WANT null pointer access. I can't remember the details but I do remember jumping to null to reset the system being pretty common.
- marshray 1y agoProbably the system interrupt table. Index 0 might reference the handler for the non-maskable interrupt NMI, often the same as a power-on reset. I recall that on DOS, Borland Turbo C would detect writes to address 0 and print a message during normal program exit.
- ghurtado 1y agoRANDOMIZE USR 0
- ncruces 1y agoIn Wasm you can read/write whatever to address zero of linear memory. It's still UB as far as clang is concerned so you C code can do whatever. But it won't “crash” on the spot.
- AdieuToLogic 1y ago> The redirect is an assignment. In no language has a variable assignment ever stopped execution. Many languages support property assignment semantics which are defined in terms of a method invocation. In these languages, the method invoked can stop program execution if the runtime environment allows it to do so. For example, source which is defined thusly: foo.bar = someValue Is evaluated as the equivalent of: foo.setBar (someValue)
- kji 1y agoIn Blink setHref is automatically bound to C++ code [1]. I think it's fair to say that anything goes. [1]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/frame/location.cc;bpv=1;bpt=1;l=145?gsn=setHref&gs=KYTHE%3A%2F%2Fkythe%3A%2F%2Fchromium.googlesource.com%2Fcodesearch%2Fchromium%2Fsrc%2F%2Fmain%3Flang%3Dc%252B%252B%3Fpath%3Dthird_party%2Fblink%2Frenderer%2Fcore%2Fframe%2Flocation.cc%235dpUtEs_gNfN7GTs_HuW1d8L5ztFqGh3JuuAWoNXHCU https://source.chromium.org/chromium/chromium/src/+/main:thi...
- sintax 1y agoUntil they don't. A common issue is not checking if the execve() actually worked and thinking nothing after the execve() will execute, which is an assumption that it not always true.
- jacquesm 1y agoSee, that's what they meant about making assumptions upthread: https://man7.org/linux/man-pages/man3/atexit.3.html https://man7.org/linux/man-pages/man3/atexit.3.html
- Arch-TK 1y agoAssigning to `window.location.href` has a side effects. The side effect is that your browser will navigate to wherever you assigned, as if you had clicked a link. This is already a surprising behaviour, but given that this assignment is effectively loading a new page in-place, kind of like how `execve` does for a process, I can totally see how someone would think that JS execution would stop immediately after a link is clicked. It's obviously not a good idea to rely on such assumptions when programming, and when you find yourself having such a hunch, you should generally stop and verify what the specification actually says. But in this case, the behaviour is weird, and all bets are off. I am not at all surprised that someone would fall for this.
- ngruhn 1y agoI use JavaScript for ~15 years. I thought it worked like that.
- svieira 1y agoI'm pretty sure it did used to work the other way. Even if it didn't something changed recently so that the "happen later" behavior was significantly more likely to be encountered in common browsers.
- stouset 1y agoPart of the problem is that we unknowingly make a million little assumptions every day in the course of software development. Many of them are reasonable, some of them are technically unreasonable but fine in practice, and some of them are disasters waiting to happen. And it's genuinely hard to not only know which are which, but to notice even a fraction of them in the first place. I'm sure I knew the href thing at one point. It's probably even in the documentation. But the API itself leaves a giant hole for this kind of misunderstanding, and it's almost certainly a mistake that a huge number of people have made. The more pieces of documentation we need to keep in our heads in order to avoid daily mistakes, the exponentially more likely it is we're going to make them anyway. Good software engineering is, IMHO, about making things hard to hold the wrong way. Strong types, pure functions without side effects (when possible), immutable-by-default semantics, and other such practices can go a long way towards forming the basis of software that is hard to misuse.
- jemiluv8 1y agoThis is more a control flow issue than a data race issue. I've seen this countless times. And it is often a sign that you don't spend too much time writing JavaScript/Typescript. You get shot in the foot by this very often. And some linters will catch this - most do actyally
- drdrey 1y agoOP thought the redirect was synchronous, not that it would stop the script from executing
- jibal 1y agoNo, you're mistaken. Read the other comments under the parent. If it were synchronous then it would have stopped the script from executing, much the way POSIX exec() works. If the OP didn't think that the script would stop, then why would he let execution fall through to code that should not execute ... which he fixed by not letting it fall through?
- drdrey 1y agoI see, thanks
- IshKebab 1y agoWhenever someone talks about a surprising paper cut like this you always see misguided "this is obvious" comments. No shit. It's obvious because you literally just read a blog post explaining it. The point is if you sprinkle dozens of "obvious" things through a large enough code based, one of them is going to bite you sooner or later. It's better if the language helps you avoid them.
- Humphrey 1y agoWhether you think that or not is not the issue - the fix is very obvious once pointed out to you. The arguement the author is making is that a bug like that TS issue can be very difficult and time consuming to track down and is not picked up on by the compiler.
- masklinn 1y ago> Seriously, why would you think that assigning a value would stop your script from executing? This assignment has a significant side-effect of leaving the page, assuming this is immediate rather than a scheduled asynchronous action is not unfair (I’m pretty sure I assumed the same when I saw or did that).