HNHacker News
TopNewBestAskShowJobs

pcwalton

43,683 karma · joined August 22, 2009

submissionscomments
pcwalton··on C and C++ prioritize performance over correctness (2023)
The first example program that demonstrates arrays in The C Programming Language 2nd edition (page 22) uses signed integers for both the induction variable and the array length (the literal 10 becomes int).
pcwalton··on C and C++ prioritize performance over correctness (2023)
> The C language does not specify that `int` is 32-bits. That is a choice made by compiler developers to make compiling non-portable code written for 32-bit platforms easier, because most codebases wind up baking in assumptions about variable sizes.

Making int 32-bit also results in not-insignificant memory savings.

pcwalton··on C and C++ prioritize performance over correctness (2023)
> Anything from making it implementation defined to unspecified behavior to just throwing a diagnostic warning or having a clang-tidy performance rule.

To be clear, you're proposing putting a warning on "for (int i = 0; i < n; i++)"? The most common textbook way to write a loop in C?

> I'm also incredibly suspicious of the idea that FAANG in particular won't accept minor compiler slowdowns for useful safety.

I worked on compilers at FAANG for quite a while and know quite well how these teams justify their existence. Telling executives "we cost the company $1M a quarter, but good news, we made the semantics of the language easier for programming language nerds to understand" instead of "we saved the company $10M last quarter" is an excellent strategy for getting the team axed next time downsizing comes around.

pcwalton··on C and C++ prioritize performance over correctness (2023)
I was disappointed that Russ didn't mention the strongest argument for making arithmetic overflow UB. It's a subtle thing that has to do with sign extension and loops. The best explanation is given by ryg here [1].

As a summary: The most common way given in C textbooks to iterate over an array is "for (int i = 0; i < n; i++) { ... array[i] ... }". The problem comes from these three facts: (1) i is a signed integer; (2) i is 32-bit; (3) pointers nowadays are usually 64-bit. That means that a compiler that can't prove that the increment on "i" won't overflow (perhaps because "n" was passed in as a function parameter) has to do a sign extend on every loop iteration, which adds extra instructions in what could be a hot loop, especially since you can't fold a sign extending index into an addressing mode on x86. Since this pattern is so common, compiler developers are loath to change the semantics here--even a 0.1% fleet-wide slowdown has a cost to FAANG measured in the millions.

Note that the problem goes away if you use pointer-width indices for arrays, which many other languages do. It also goes away if you use C++ iterators. Sadly, the C-like pattern persists.

[1]: https://gist.github.com/rygorous/e0f055bfb74e3d5f0af20690759...

pcwalton··on Towards fearless SIMD, 7 years later
I can't quite parse your statement, but if you mean that bytemuck doesn't let you "rely on the exact binary layout of something in memory", then yes, it does: it lets you cast from a Pod type to another Pod type, which exposes the memory layout of both types.
pcwalton··on One island, two worlds (Haiti vs. Dominican Republic)
Feudalism is the literal opposite of a highly functional centralized state! And you said 1,000 years, which extends well before the Edo period, even if you consider the Edo period a centralized state (which I would not--the establishment of a centralized state is what characterized the Meiji Restoration).
pcwalton··on One island, two worlds (Haiti vs. Dominican Republic)
On the contrary, there ended up being not much continuity between pre-Meiji Japan and Meiji Japan--the daimyo's domains were replaced with prefectures and the daimyo themselves were largely forcibly retired. This was intentional on the part of the Meiji oligarchy, in order to prevent the daimyo from retaining enough power to be able to rebel [1]. The Meiji Restoration was an enormous change in Japan's government, really from top to bottom.

[1]: https://en.wikipedia.org/wiki/Abolition_of_the_han_system

pcwalton··on One island, two worlds (Haiti vs. Dominican Republic)
What? This is totally ahistorical. The Meiji era (the beginnings of what we might call a modern Japanese state) didn't start until 1868. Before that, Japan was feudal with wars happening all the time. Quoting from Wikipedia about the infamously-chaotic Sengoku period in the 1400s [1], which was just one of many turbulent times prior to the Meiji period:

> The period saw a breakdown in the traditional master-servant relationship between a lord and his vassals, with many instances of vassals rebelling against their lords, internal dynastic conflict over lordships within noble families (in which vassals would take sides), and the installation of figurehead lords by cadet branches of noble families.[3] The period was also marked by the loosening of samurai culture, with people born into other social strata sometimes making a name for themselves as warriors and thus becoming samurai.

> [W]eariness of war, socioeconomic unrest and poor treatment by aristocrats provoked the wrath of the peasant class. Farmers, craftsmen, merchants and even villages would organize uprisings (known as "ikki") against the ruling class. An extraordinary example is the Kaga Rebellion, in which the local ikki had staged a large-scale revolt with the support of the True Pure Land sect (thereby establishing the term ikkō ikki) and assumed control of the entire province of Kaga.

Whatever post-Heian, pre-Meiji Japan was, it was not an orderly, harmonious society.

[1]: https://en.wikipedia.org/wiki/Sengoku_period

pcwalton··on Rust Any part 3: we have upcasts
> Turns out monomorphization isn't all you need. Turns out that it is, in fact, occasionally useful to unify an object and its behavior in a runtime-polymorphic way.

This actually gets the history backwards. Ancient Rust tried to do generics in a fully polymorphic way using intensional type analysis, like Swift does. We switched to monomorphization reluctantly because of the code bloat, complexity of implementation, and performance problems with intensional type analysis. "dyn Trait" was always intended to be an alternative that code could opt into for runtime polymorphism.

pcwalton··on xAI has acquired X, xAI now valued at $80B
Bad timing on your post. Just today, Elon tried to get content he didn't like taken down from Reddit, using specious legal reasoning: https://mashable.com/article/elon-musk-messaged-reddit-ceo-o...
pcwalton··on Towards fearless SIMD, 7 years later
> As far as I can tell, any time you want to rely on the exact binary layout of something in memory, you need unsafe. As a corollary, any time you want to bit cast from one type to another, you need unsafe.

No, that's what bytemuck is for. If bytemuck didn't exist, sure, I'd be using a lot of unsafe.

pcwalton··on Towards fearless SIMD, 7 years later
> I have been working on some software in Rust recently that needs bit and byte manipulation, and we have "unsafe" everywhere and hugely complicated spaghetti compared to the equivalent code in C.

I'm curious what makes this so different from my experience. I rarely ever have to write "unsafe", and I'm writing quite low-level engine code that certainly uses bit manipulation. In fact, crates like bitflags and fixedbitset make it so easy that I tend to get dinged in code reviews for using bit flags when structs of booleans would be simpler :)

pcwalton··on Towards fearless SIMD, 7 years later
> Even before getting into SIMD, try using Rust for concurrent, succinct, or external-memory data structures. It quickly becomes clear where the friction is.

It's the exact opposite for me: I use concurrent data structures more often in Rust than I do in C++ because I don't have to worry about dumb data race bugs. If one of my Bevy systems is slow, I slap par_iter() on the query and if it compiles it probably works, or at least fails for a not-stupid reason.

pcwalton··on Towards fearless SIMD, 7 years later
> I can't comment on DB because that is quite far out of my wheelhouse but regarding game engines, I've almost universally seen people revert to storing objects in arrays and passing around "handles" which is literally pointers with extra steps... But I guess at least you are protected from some issues there.

Regarding game engines, the empirical evidence shows that Bevy has been moving at least as fast as, if not faster than†, comparable C++ engines. I listed all the features I landed in the past year here: https://news.ycombinator.com/item?id=42945730

We love to argue on message boards about theoretical or anecdotal productivity of programming languages, but at the end of the day the only thing that matters is what people have actually been doing with the language, and for Rust the answer is "quite a lot, actually".

†In my view, Bevy has been moving significantly faster than comparable C++ engines, but I don't need to argue that to make my point.

pcwalton··on xAI has acquired X, xAI now valued at $80B
> Musk has made no attempt to suppress speech on Bluesky, Facebook, Reddit, Tiktok, etc.

This is false if "etc." includes Wikipedia, on which Musk has attempted to suppress speech critical of him [1].

[1]: https://theweek.com/media/elon-musk-wikipedia-controversy

pcwalton··on Abundance isn't going to happen unless politicians are scared of the status quo
Huh, California's bar exam has a 54% pass rate, while Indiana's has a 73% pass rate. TIL!
pcwalton··on Waymos crash less than human drivers
> Someone willing to operate a motor vehicle without a license is one step away from manslaughter.

I suspect there are plenty of undocumented immigrants in states that don't have the equivalent of AB 60 licenses who are perfectly safe drivers. Perhaps even safer than licensed drivers, since they have more to lose from moving violations.

pcwalton··on Blasting Past WebP - An analysis of the NSO BLASTPASS iMessage exploit
They have some kind of safe dialect of C that they use for iBoot. Also they're increasingly using Swift for things.
pcwalton··on A love letter to the CSV format
> Unlike XML or JSON, there isn't a document defining the grammar of well-formed or valid CSV files

There is such a document: RFC 4180. It may not be a good document, but it does exist.

pcwalton··on Samsung CEO Jong-hee Han has died
The emphasis on filial piety in east Asian cultures is undeniable, but I think this thread is overlooking the significant complication that east Asian countries also have some of the lowest birth rates in the world. Americans have more kids than the Japanese, for instance--not fewer--and birth rates across southeast Asia are collapsing, including in China.
pcwalton··on Tesla sales drop 35% in San Diego County
San Diego County was D+17 at the presidential level in 2024, not exactly right-leaning in national terms. It's slightly right of California (D+20) as a whole, I suppose.
pcwalton··on Shift-to-Middle Array: A Faster Alternative to Std:Deque?
Oh, I see, it's actually on Wikipedia [1]. I figured I wasn't the first one to invent the idea :)

[1]: https://en.wikipedia.org/wiki/Circular_buffer#Optimization

pcwalton··on Shift-to-Middle Array: A Faster Alternative to Std:Deque?
Interesting alternative idea I thought of just now: a data structure that works like VecDeque (a circular buffer) but uses mmap to map two views onto the same pages right after one another. That would ensure that the entire array can be accessed in a consecutive fashion, no matter where it gets split, without any copying. The downside is that reallocation would be really slow, involving multiple syscalls, and the minimum size of the array would be 4kB or more, depending on the page size.
pcwalton··on Crabtime: Zig’s Comptime in Rust
The point I'm making is that I don't believe Zig can be made meaningfully memory safe without breaking compatibility to the extent that memory-safe Zig would effectively be a different language, any more than C can.
pcwalton··on Crabtime: Zig’s Comptime in Rust
Assuming by "non-Rust types" you mean "those that the bevy_reflect crate doesn't know about", it's indeed limited by the orphan rule. That being said, bevy_reflect offers many workarounds for this problem. Because bevy_reflect is based on a type registry containing function pointers, you can actually populate it manually for types external to your crate without using the Reflect trait at all if you want to. And if your type contains fields that aren't Reflect, then you can use custom reflection logic.
pcwalton··on Crabtime: Zig’s Comptime in Rust
We Bevy users use Rust reflection on a daily basis, and are very happy with it :)

I agree it'd be nice if it weren't confined to our community, though.

pcwalton··on Crabtime: Zig’s Comptime in Rust
I have seen projects like that, and they're a prime example of what I mean when I want to see arguments in favor of Zig that rely on what Zig can do now, and not what it could potentially do in the future. Ten years ago, C++ folks were also promising memory safety with the ISO C++ Core Guidelines; you don't hear much about that anymore, because it turns out it can't be done while keeping the resulting language C++ (for example, seanbax's work for C++, which is far more advanced than this project, is really awesome, but is essentially a different language).
pcwalton··on Crabtime: Zig’s Comptime in Rust
> The challenge is balancing the value of features with their complexity. Even those who prefer Rust's aesthetics to Zig would admit that Zig's novel approach to power/simplicity balance is something we have not seen in programming language design in many years.

I disagree. Minimalism in systems language design has been done over and over: see Go for the most recent example. Comptime is something that C++ was already doing in the form of constexpr since 2011 and a space that D had explored for over a decade before Zig came around in the form of "static if" and so forth (in addition to lots of academic work, of course). Stripping out template metaprogramming in favor of leaning heavily on compile-time function evaluation isn't novel either. I think you find the set of features that Zig has to be personally appealing, which is fine. But the argument that it's anything novel is weak, except in the trivial sense that every language is novel because it includes some features and leaves others out (but if every language is novel, then the word "novel" has no meaning).

From my vantage point, Zig is essentially a skin on a subset of C++, one that is in practice less safe than C++ because of the relative immaturity of tooling.

pcwalton··on Crabtime: Zig’s Comptime in Rust
Such as the one Rust provides, and that Zig cannot, due to not being memory safe.
pcwalton··on Crabtime: Zig’s Comptime in Rust
There are various reflection crates available on crates.io, as you know.
← PreviousPage 4 of 34Next →