With all the discussion on the STL, I wanted to make a quick thread to summarize the main reasons why many AAA studios (correctly) opt out of the STL. This isn't to say the STL isn't for anyone, but the reasons to avoid using it aren't unfounded either 1/🧵
The STL implementation varies depending on platform/compiler choice. This seems like a small matter, but sometimes we need the functions to behave in a controlled manner across all platforms. 2/n
Consistent behavior means similar execution order, deterministic results in scenarios where determinism matters, and even a consistent ABI you can rely on to share code between compatible platforms. 3/n
Furthermore, you have a consistent debugging experience (and a fast one, if reasonably fast debug builds are a priority for you, which they absolutely are in AAA). 4/n
Another thing about the STL is that it simply wasn't designed with tracking in mind. That is, attributing memory allocations accurately. It's not good that just "push_back" can result in an allocation you can't track. You could use custom allocators but... 5/n
...custom allocators in the STL are really difficult to use. This is probably more opinion than fact, but I think the interfaces I've worked with in the games industry are a lot easier to grok than std::pmr and using the allocator trait. 6/n
In many cases, the STL is actually flat out missing functionality that requires intrusive changes to add or correct. For example, adding elements to containers without initializing. Unsafe scary behavior? Sure but we need escape hatches on hot paths! 6/n
In some cases, the STL enforces various semantics that you don't need that hurt performance. For example, iterator stability is something that imposes restrictions on container implementation you don't always need. 7/n
Another good one is std::shared_ptr which supports std::weak_ptr. The mere fact that the implementation needs to support a notion of weak_ptr at all affects the implementation! 8/n
Error handling vs exception handling is another popular one. It's true that exception overhead when the exception is not thrown is negligible, but several aspects of the STL uses exceptions for common error cases you'd expect to encounter. 9/n
You can, of course, disable exceptions, use the error variants, etc. But the fact remains that the primary APIs were designed expecting exceptions to be around, as opposed to being designed around more performant error handling from the get-go. 10/n
In short, to me, the main pitfalls of STL are related to uniformity, debuggability, performance, and design. These aren't problems that you can solve by "bolting stuff onto the STL." Given how foundational these concepts are, people shouldn't be surprised that AAA rolls their own
off by 1 error in the thread numbering oops ignore pls thanks
Last note: of course, I use the STL where appropriate in personal projects, when interfacing with other libraries, or cases where none of the reasoning above applies. As with most things in engineering, it's not black and white so use your judgement. /🧵
A little sloppy with my language here, but when I wrote "ABI" here, I was referring to "data layout" (struct member sizes, order, etc.), and not "calling convention"