HNHacker News
TopNewBestAskShowJobs

StephanTLavavej

884 karma · joined July 20, 2014

Principal Developer, Visual C++ Libraries. Pronounced Steh-fin Lah-wah-wade, prefers STL.

Home: stl@nuwen.net

Work: stl@microsoft.com (I work for Microsoft, but I don't speak for them.)

submissionscomments
StephanTLavavej··on Rejuvenating the Microsoft C/C++ Compiler
FYI, C99 printf including 'z' for size_t was fully implemented in VS 2015.
StephanTLavavej··on The Sustainability Solution to the Fermi Paradox (2009)
> The only solid solution to the Fermi Paradox that does not require some new and presently missing piece of scientific understanding

There's at least one more: somebody's gotta be first (in our light cone).

StephanTLavavej··on Implementing a lightweight task scheduler in C++
And in fact, VC's volatile behavior provides only acquire-release, not full sequential consistency. SC is required for the correctness of some algorithms, and it's what programmers intuitively expect, so <atomic> provides it by default.
StephanTLavavej··on C++ Internals: STL Vector, Part 3
No, that was forbidden by the resolution of Core Issue 1669, see: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html...
StephanTLavavej··on C++ Internals: STL Vector, Part 3
Yep, that's a totally counterproductive use of trailing return types. There are several reasons to use trailing return types, but that's not one of them. (The major use is when you have to refer to function parameters with decltype. Additional uses are when the return type would have to be qualified on the left but can be shorter on the right, or when you're returning something like a function pointer or reference to array and you don't have a convenient typedef/alias.)
StephanTLavavej··on C++ Internals: STL Vector, Part 3
It's amusing to see somebody going through work I did 8 years ago!
StephanTLavavej··on C++ Internals: STL Vector, Part I
Old auto was completely removed.
StephanTLavavej··on C++ Internals: STL Vector, Part I
auto variables are different from trailing return types introduced by auto (a particularly egregious appropriation of a keyword for a totally different use).
StephanTLavavej··on More Dirty Coding Tricks from Game Developers (2010)
You're incorrect, for C89 through C++17. I'd recommend not making statements about languages you've forgotten.

In the C++ Working Paper, the Standardese is N4527 5.2.2 [expr.call]/4 "When a function is called, each parameter (8.3.5) shall be initialized (8.5, 12.8, 12.1) with its corresponding argument." followed by 8.5 [dcl.init] where /17.8 has a nice example:

"Note: An expression of type "cv1 T" can initialize an object of type "cv2 T" independently of the cv-qualifiers cv1 and cv2. int a; const int b = a; int c = b;"

(A "cv-qualifier" is const or volatile; they behave similarly in many contexts, hence the collective terminology for convenience.)

StephanTLavavej··on GCC: Patch to change default C++ dialect to C++14
Yep. (TR1 was published after C++03, they're totally different things.) What we did with TR1 was actually very friendly to migration - we provided std::tr1::meow in <meow> (in 2008 SP1), then in 2010 we aliased that to std::meow as C++0x was being finalized, then in 2012 we switched the True Name to std::meow and made std::tr1::meow the alias for back-compat. At some point in the future we'll probably remove the tr1 aliases completely.

For the Technical Specifications, we're following their header directory and namespace rules (<experimental/meow>).

StephanTLavavej··on GCC: Patch to change default C++ dialect to C++14
If we changed __cplusplus before implementing every single C++11 feature, the Internet would riot.
StephanTLavavej··on C++11/14/17 Features in VS 2015 RTM
It's entwined, and has been for nearly a decade. MS licensed Dinkumware's STL back in the mid-90s (and I know almost nothing about the early history). Around 2005, MS was doing things like adding security features to the STL, but not really sustained development. In Jan 2007, I joined the VC team and since then I've spent almost all of my time on the STL (with one brief detour). For a long time, I fixed bugs, dealt with MS-specific stuff (DLLs, calling conventions), reported compiler bugs, that sort of stuff, with PJP delivering new features (starting with TR1 in 2008 SP1). I review all STL checkins, preventing bugs from happening in the first place. In the last few years, I've tackled larger overhauls and started implementing larger features. For example, in this release I rewrote the TR1-era <functional> implementation (keeping only std::function's skeleton), implementing C++17 invoke() as a side effect.

Other MS devs have contributed STL bugfixes in this release, and a couple of features (e.g. uncaught_exceptions() and sized deallocation), so it's not just the PJP and STL show.

StephanTLavavej··on C++11/14/17 Features in VS 2015 RTM
Heh! Nobody's ever called me a collective entity before.

I just happen to enjoy writing and keeping track of these feature tables, which is why I publish them. My real work goes into STL features and fixes, which is just one part of a very large product that many other compiler and library devs work on.

StephanTLavavej··on C++11/14/17 Features in VS 2015 RTM
It was a close call, but we got it done just in time. (It took a month and a half to constexprize the STL. I went through 84 shelveset revisions, which would be like feature branch checkins in git, and that's not counting the numerous compiler fixes that Tanveer, our front-end dev working on constexpr, checked in.)
StephanTLavavej··on C++11/14/17 Features in VS 2015 RTM
Yes. In fact, the usual mechanism for doing so is referred to as tag dispatch. For example, an algorithm can take an arbitrary Iterator type, and select between a correct-but-slow algorithm for weak iterators like forward iterators, and a fast algorithm for strong iterators like random-access iterators. The easiest way to achieve this is to call a helper function and pass a tag object whose type is iterator_traits<Iterator>::iterator_category, which might be forward_iterator_tag or random_access_iterator_tag. The helper function is then overloaded on those tags, achieving the effect of a compile-time if. Everything optimizes away (the compiler is very good at noticing do-nothing tag objects).

Expression SFINAE offers the ability to detect more properties of things, like is_callable or has_member_function_meow. This can then be used in tag dispatch, or other mechanisms (SFINAE can be used directly to dispatch, but it's a more lengthy explanation).

StephanTLavavej··on C++11/14/17 Features in VS 2015 RTM
Yeah, being able to determine the validity of arbitrary expressions at compile time is extremely useful for libraries. For example, it allows libraries to sense the presence of member functions in user-defined types, calling them when present and falling back to default behaviors when missing.
StephanTLavavej··on Nantero Exits Stealth: Using Carbon Nanotubes for Non-Volatile Memory
It's roughly 3000 cycles. Yes, three thousand. See: http://www.anandtech.com/show/7237/samsungs-vnand-hitting-th...
StephanTLavavej··on Graph Engine vs. C++ unordered_map: memory consumption test, Part 2
VCBlog is the VC team's official blog. See http://blogs.msdn.com/b/vcblog/archive/2014/06/06/c-14-stl-f... for where I announced the alignment thing.
StephanTLavavej··on Graph Engine vs. C++ unordered_map: memory consumption test, Part 2
Yeah, unordered_meow is always going to be a pretty crummy hash table. But our implementation could be significantly improved while still obeying the Standard.
StephanTLavavej··on Graph Engine vs. C++ unordered_map: memory consumption test, Part 2
Nope, our sources assume they're running on Windows.
StephanTLavavej··on Graph Engine vs. C++ unordered_map: memory consumption test, Part 2
By default, std::allocator just wraps new, so it doesn't make things any harder to measure. vector isn't "allocating extra space" for no reason - its capacity grows geometrically in order to provide amortized O(1) push_back. If you use reserve() incorrectly, you can actually trigger quadratic complexity (as I've done in the past when I didn't know any better). Even with unused capacity, vector is quite space-efficient. For example, with GCC's 2x growth, on average a vector will be using 33% extra space (that's 0.5/1.5). With VC's 1.5x growth, on average a vector will be using 20% extra space (that's 0.25/1.25). That's a pretty small cost to pay for vector's optimal locality. And in practice, many containers will actually be exactly-sized (range construction and copy construction will produce exact sizing), so the overhead is even lower.
StephanTLavavej··on Graph Engine vs. C++ unordered_map: memory consumption test, Part 2
You're welcome! And even if you don't use VC's STL, hopefully make_unique and the other things I've designed will be helpful.
StephanTLavavej··on Graph Engine vs. C++ unordered_map: memory consumption test, Part 2
And recently (in 2013, I forget about previous versions) the CRT began using the process heap, instead of having its own heap handle. So the malloc/new/std::allocator family is an even thinner wrapper around HeapAlloc in that sense.

(In 2015, we're introducing a little bit of extra trickery though. In std::allocator, we'll highly align large allocations to be friendly to autovectorization. This isn't done at the lower malloc/new levels because they don't get size information at deallocation time, but the std::allocator interface has always required that information even if it was previously ignored. IIRC this buys 15% or so, which makes the back-end devs drool. Our current magic number for "large" is 4 KB, so this basically never affects node-based containers, only stuff like big vectors.)

StephanTLavavej··on Graph Engine vs. C++ unordered_map: memory consumption test, Part 2
I bookmarked those posts a while ago in the hopes that I'll get a chance to rewrite VC's unordered_map in the future. We've taken the first step towards doing so by deprecating the non-Standard hash_map (which shares its guts with the Standard unordered_map) in 2015, so I can remove it outright at the beginning of the next development cycle. Then the unordered family can be changed without fear of breaking the hash family.
StephanTLavavej··on GiveDirectly Gives Poor People a Year's Income
8/7000 is 0.11%.
StephanTLavavej··on C++11/14/17 Features in VS 2015 RC
See the FAQs at the bottom of the post: "Q. I want Expression SFINAE." and "Q. When will you implement Expression SFINAE?".
StephanTLavavej··on C++11/14/17 Features in VS 2015 RC
Thanks! I just try to follow the meta-golden rule: treat your users as you would prefer to be treated by your implementers.
StephanTLavavej··on C++11/14/17 Features in VS 2015 RC
The C99 Standard Library has been completed in 2015, including snprintf, with the exceptions noted in my post (tgmath.h and pragma macros).
StephanTLavavej··on C++11/14/17 Features in VS 2015 RC
VC's current lack of an AST makes constexpr and other major features (especially variadic templates) very difficult. As the compiler devs have explained to me, this was a clever way to save space and time decades ago when C++ was simpler to compile. Features like constexpr and variadic templates make C++ easier to use, but they demand much more from the compiler's data structures.
StephanTLavavej··on C++11/14/17 Features in VS 2015 RC
Bingo. We have a test that includes windows.h followed by all STL headers, to verify that we always remember the parens.
← PreviousPage 4 of 6Next →