6 ms·
The Windows operating system. Windows is quite an engineering achievement. We didn't prioritize readability or "clean code". All the variables used hungarian n
by rsweeney21 7y ago
The Windows operating system.
Windows is quite an engineering achievement. We didn't prioritize readability or "clean code". All the variables used hungarian notation, so you had horrible names like lpszFileName (lpsz = long pointer to a zero terminated string) or hwndSaveButton (window handle). You also had super long if(SUCCEEDED(hr)) chains that looked like your code was spilling down a staircase. Oh yeah, and pidls (pronounced "piddles" and short for "pointer to an id list") used for file operations.
What made the code base beautiful was the extreme lengths we went to to be fast and keep 3rd party software working. WndProcs seem clunky, but they are elegant in their own way and blazingly fast. All throughout the code base you would find stuff like "If application = Corel Draw, don't actually free the memory for this window handle because Corel uses it after sending a WM_DESTROY message."
The fact that thousands of people worked on the code base was mind boggling.
- cryptica 7y agoThe Windows API was very ugly... not to mention unnecessarily complicated. It does not belong in this thread.
- holy_city 7y agoPersonally, COM gives me the heebie-jeebies. I get why it exists and think it's a cool idea. Under the hood it's just RTTI across shared library boundaries, and it's cool that it "just works" with the way that compilers generate vtables from pure virtual base classes. But hell did it take me awhile to figure out how that worked because it's so poorly documented and auto-magical. Reverse engineering a COM DLL just to find out how the hell it has a stable ABI is not fun.
- inlined 7y agoAlso the whole point of COM was interface composition which led to the diamond problem (multiple inheritance) in any real C++ object that implemented two interfaces (which each had to inherit IUnknown if all implementations were to be COM compatible). Virtual inheritance was a hack fix to a platform whose primary language fought its primary purpose.
- holy_city 7y agoTrue. That. I've spent a fair amount of weekend time over the last couple months working on a non-standard COM API port to Rust, and the one thing that's stuck me the most is how batshit crazy relying on virtual base classes is for an extensible API. It only works when you want users to deal with your C++ SDK, not the API itself.
- mehrdadn 7y agoSome parts are ugly, some are beautiful. You can't really lump it into one bucket.
- deleted 7y ago[deleted]
- c-smile 7y agoI have quite opposite opinion backed by real life experience. As an author of Sciter Engine that works on Windows, MacOS and Linux/GTK I have first hand experience working with all three API sets. Windows API is the most logical, complete and stable API among all others. It has everything that you really need to create performant and manageable UI. MacOS is good but less good. It uses reference counting (which is not bad by itself) but in very strange manner. Name of the function determines need of [obj retain] / [obj release] and not all names that they use are consistent in that respect. Yet Apple changes API quite frequently and dramatically. GTK, while is built on top of quite reliable Glib foundation is a mess to be honest. You have GtkWindow and GdkWindow, you have gtk_window_resize(), gtk_window_set_default_size() and 6 more functions that should allow to set size of the window but they may or may not work in particular situations.
- tempguy9999 7y agoIIRC there were three different kinds of handles, the documentation was a crock, the api did minimal checking, it was horrible. Fast maybe, but delphi succeeded so well because it hid all the awfulness. MS just didn't get it for years.
- c-smile 7y agoYes, there are problems but if to compare with others... Windows is so popular just because of stability and completeness of its API. And that is non-disputable I think. Quite few simple and flexible abstractions (handles, WndProc, messages, etc).
- mehrdadn 7y ago> GTK, while is built on top of quite reliable Glib foundation is a mess to be honest. You have GtkWindow and GdkWindow, you have gtk_window_resize(), gtk_window_set_default_size() and 6 more functions that should allow to set size of the window but they may or may not work in particular situations. You know, even as a guy who loves Windows, this example makes my head explode. We have MoveWindow, SetWindowPos, SetWindowPlacement, DeferWindowPos, ShowWindow, ShowWindowAsync etc. all of which overlap in functionality. Similarly SetActiveWindow and SetForegroundWindow, etc...
- criddell 7y agoThe number of cycles that have been wasted checking for Corel Draw must be astounding. I wonder if an environmental cost could be calculated for something like that.
- tempguy9999 7y agoI'm mega curious about this > ...like lpszFileName (lpsz = long pointer to a zero terminated string) I remember those. AIUI hungarian gives you some kind of typing. The typing is done by humans using the names. The humans have to get it right; they are the typecheckers. The first thing I'd do is offload the typechecking onto an automatic framework - the idea of letting people do a computer's job is madness. It would not have been too hard to do (relatively very cheap for a large codebase like an OS), I think, and would have allowed the hungarian prefixes to be dropped because they'd become redundant, and strengthened and speeded up typechecking. So where is the flaw in my thinking? (aside: one of my first contract jobs was working in pascal (delphi actually). The company I worked for had coding standards cos you need standards, don't you. It was to prefix every integer with i_, every float with f_, every int array with ai_, et cetera. As pascal was strongly typed this was totally pointless).
- tempguy9999 7y agoWould whoever downvoted this please explain why. I laid out my thoughts for critiquing by others, but learn nothing unless I'm told why it's wrong.
- inlined 7y agoI’ll save you with an upvote. Hungarian notation also helps avoid collisions that lead to confusingly similar names: pArray (array pointer) ecArray (element count of array) bcArray (byte count of the full array)
- MagnumOpus 7y ago> So where is the flaw in my thinking The codebase has 34 years worth of code written already, 100 million LOC or more if you count Office, VS etc. The cost of typechecking is trivial but the cost of rewriting this much code to be consistent with any new convention is in the hundreds of millions of dollars. This legacy cost then of course becomes higher every year...
- inlined 7y ago
- breck 7y agoI once tried to add a feature to Windows (back in the sd days), and it was a nightmare. I was in the C&E org so it was a side project thing, and I eventually postponed it (but then left MS so never got it finished). I imagine it's gotten much better since then, in large part from the shift to git alone. It certainly was super impressive feat for the shear scale and longevity. I have a lot of respect for the folks who make that beast work. And there are bits of it that are brilliant. But it was an ugly beast.
- inlined 7y agoI worked on Windows for 3.5 years and hated most the code I touched: 1. I think I counted 5 string implementations in active use and code at the boundary had to convert between them all. 2. The SUCCEEDED macro is a mask against HRESULT but who the hell actually uses non-zero HRESULTS to communicate domain-specific success codes? And don’t forget that posix APIs return 0-for-non-error ints and COM APIs can use S_TRUE (0 to be a non-error) and S_FALSE (1) so you have to flip them for real bools. Or have if (bResult == S_TRUE) 3. Nobody wanted to touch old codebases. I fixed an assert in Trident layout code because a whole library used upper-left, lower-right input (and params called ul, lr) but one function (contrary to docs) used upper-left, width, & height. When I fixed the library and 2/3 call sites I was called arrogant, to revert changes in the library, and change the last 1/3 to also have the inverse bug in its call-site. 4. Another Trident API (written by an intern) had a tree where fastInsert() could only be called after slowLookup() but nothing in the api enforces this 5. Every COM object decides whether it’s faster or thread-safe by whether the refcount uses atomic ops or just —/++ 6. Saw parallel arrays in files where a struct held an object which might have suffered the slicing problem in insert. Another struct field held an into the index of the sliced part array. Users rehydrated. This wouldn’t happen with an object pointer, but indirection was unacceptable because the author didn’t trust the small allocation heap’s locality. 7. My codebase included a while c++ runtime because my core-OS team didn’t trust msvcrt.dll because the shell team wrote it.