« Piles of "Stuff" | Main | Life Marches On »

June 15, 2007

Develops on Windows, in C++, for Windows: A Year In Review

A number of friends and former colleagues - who were surprised that I took a job developing on Windows (not as surprised as I was, I assure you) have asked, essentially, "well, what's it like?"

The executive summary is "not as bad as I feared, but I won't be giving up linux any time soon."

Read on for more.

My choice to join Valve a bit over a year ago brought me back to working in C++ for the first time since c. 1999 and doing it on Windows for the first time ever.

Coming back to C++ - as compared to Java - is easy:

1. It's the same language it was almost 10 years ago, and despite the stationary target, development tools have advanced at a snails pace compared to Java (I mean, look at the evolution of eclipse for comparison.

2. STL, after years of evolution, still isn't nearly as useful as the Java run-time library. Dealing with linkage and memory allocation across DLL boundaries hobbles it, and in our case unpredictable space/compute performance seals the deal. So yea, we've got our own container classes - and they sorta smell like STL containers, but they aren't.

3. Exceptions in C++ (compared to exceptions in Java) are like tits on a bull. Why? This, among other reasons, is why.

4. The lack of rich runtime reflection and introspection is really annoying after living in Java

6. Linkers, and link times, still suck.

Windows as a development environment is a bit more of a mystery wrapped in an enigma.

The good:

1. Visual Studio has a very nice C++ debugger. It's a far and away better interface than any debugger I've used on *nix. The closest is the Eclipse debugger, which - last I used it - wasn't nearly as nice for C++ as it was for Java.

I haven't used some of the modern C++ development environments on *nix (like Anjuta, for example), so I may just be missing the boat.

2. The minidump (essentially core dump, but with a bit more control over it's creation) mechanism coupled with the ability to pull debug info out of an exe and sitch it back together post-facto (the symbol store mechanism) are nice.

Modern linux distros do part of this (Fedora, for example, with it's debuginfo packages), but Microsoft has really provided a round-trip solution, with tools to publish symbols from builds to a symbol store and the ability to find the symbols in the store that match the binary being debugged.

The bad and the ugly:

1. The windows task and i/o scheduler could really use help. I have a dual core AMD with 4GB of memory and it's easy - painfully so - to make the machine bog. Heavy I/O (like, you know, compiling and linking) brings the machine to it's knees and interactive perf drops like a stone.

I can have my home linux box at a load average of 10+ and still have snappy interactive response, but building our server project and reading mail is enough to hobble my faster work machine.

2. There's way too much "touch" required to admin boxes - joke:

Q: "what's the best remote administration tool for windows?"
A: "a car"

Without investing in a crap-load of Microsoft "back office management" tools, there's no good way to do the equivalent of:

$ for each host in ( host1 host2 ... hostN ); do
? ssh $host some-command-here
? done

We've (ok, I've) built some capabilities into our software to give us this ability on boxes already running our server-side bits, but it's a pale shadow of a real shell scripting environment.

3. Sort of a corollary to 2 - the lack of standardized package management is a large contributor to dll hell and makes updating machines a Sisyphean task.

Every app has it's own installer, most of them can't be run unattended/headless, and only a few have the smarts to check for updates across the network. Even Msi - Microsoft's answer - is too little too late. Too little because it doesn't address the "make sure the bits on this machine are up-to-date" in a way that 3rd party vendors can easily leverage and too late because companies with investments in existing installer tech aren't likely to move just "'cause."

4. cmd syntax is a steaming pile of shit, and inventing another form of VBScript in some newfangled "windows shell" isn't going to solve my problem.

Quick - what's this do:

for /F "tokens=2* delims=:" %k in ( 'findstr drivername *.ini | findstr atapi' ) DO (
  echo %k
)
if errorlevel 1 ( 
  goto done
)
echo success
:done

Well, first of all, it doesn't work 'cause you can't have pipes in the command in the in clause.

But if you could, the "tokens=2* delims=:" magic is a (rather pathetic) subset of awk - it breaks input lines on :'s and takes the second token (and everything after).

The %k bit is the loop variable - but don't try to put this in a bat file, 'cause then you need an extra % in front of that (%%k). And those loop variables names are governed by rules that I don't understand.

So while you can write scripts in CMD - most sane folks immediately install python and the win32 extensions (or perl, if you're that kind of weirdo).

It may be a small thing, but the need to "leave" the in-built interpreter language to get anything useful done is a serious pain in the arse to someone used to having a Turing complete language at their fingertips.

Of course I've installed cygwin, but it's a hack - made sorta useless by the mismatch between windows paths (c:\foo\bar) and cygwin paths (/cygdrive/c/foo/bar) - you can't pass the latter to a windows exe and expect it to grok it, which limits the sort of scripting you can do if you've gotta interact with native windows executables.

5. The whole OS lacks layering/transparency/inspectability. I think there are layers in there, but it's hard to tell - you can't figure them out from the outside easily. I'm not even talking about daft marketing/packaging statements like "Internet explorer is part of the OS."

Some of this may just be that I've got decades of experience in *nix and I "get" the model, whereas I haven't even been able to find someone who can explain the model on Windows - and we've got plenty of ex Microsoft folks who've tried.

6. Remember what I said about Visual Studio having an excellent debugger? Well it's overall a pretty poor development environment.

First off, the build system is horrible. I'm actually pining for Makefiles for god's sake - and several of my team members agree with me. It doesn't scale to large projects, it's completely uninspectable, and it changes subtly between visual studio releases.

I recently spent a day tracking down why we got spurious project builds (build, touch nothing, build again and work was happening) to find that while in previous versions / and \ were treated the same - now (VS 2k5) /'s in path names are seen differently by the actual tools (compiler, linker, etc.) than by the build system which calculates dependencies. Editing vcproj files through the UI is painful, so I ended up firing up emacs and editing the XML by hand.

Turns out many core groups at Microsoft don't use the Visual Studio build system - and I can't blame them a bit.

The editor is trying hard to be good, and it has some nice features, but it's no emacs. With a combination of Visual Assist and lengthy periods customizing the keybindings, it's livable.

There's more to say, but it's taken me long enough to get this much worked into reasonable form. More later, perhaps.

Posted by dberger at June 15, 2007 8:59 AM

Comments

A few months late, but figured I'd share a few links for ya:



Emacs.NET, newly underway:



http://www.douglasp.com/blog/2007/12/27/EmacsNet.aspx



And re: command-line scripting, have you tried Powershell? You probably have by now, but if you haven't, you should -- it's pretty great:



http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx



Lastly, for what it's worth, I've been working with Eclipse as well now for several months, and even as a seasoned Visual Studio guy, I much prefer Eclipse, too. :) (Still looking forward to Orcas, though...)



Cheers,

Chris

Posted by: Chris Nunciato at January 1, 2008 11:59 AM