Friday, September 26, 2008


So, I'm trying something simple: redirect the output of a command to a file.  For no obvious reason, the utility decided that some of the data was 'stdout' and the rest was 'stderr'.  So all I need to do is the 2>&1 redirect trick, right?

Right.  But it's much stranger than that.

cvs annotate >data.dat 2>&1

is the correct command.  The wrong command is 

cvs annotate 2>&1 >data.dat

See the very subtle difference?  I sure didn't.  Because it didn't work right away, I had to start debugging it -- was it really putting output into those two pipes? (yes).  Can I pipe them each, one at a time? (yes)  Can I google for the correct syntax (yes).  Nowhere did I see the warning: you must do the 2>&1 pipe AFTER the >data.dat redirect.

Interestingly, if you first redirect output 1 (stdout), then pipe output 2 (stderr) into 1, then redirect output 1 to a diferent file, output 2 goes to the console.  I'd expect it to go into one of the two files that 1 was redirected to.  And output 1 eventually goes to the last file it was directed to.

ObLink: Microsoft badly documents the pipe operators at:

Tuesday, September 2, 2008

Dreaded LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs

Perhaps the most irritating misfeature in the Microsoft compiler/linker family is the complete inability to make proper library files. What's a library file, you ask? Simple: it's where one person writes a bunch of code in a nice high-level language and then converts it into a single, neat "lib" file that a second person can then use in their program.

Conceptually, it's a no-brainer. Getting a good implementation of this, though, is beyond Microsoft's ability. It's easy to make a library -- it's just not possible to make a library that an arbitrary other person can use. (I'm currently interfacing a small program to Erlang; they have to ship three different libraries on Window just to get around the issues).

Microsoft keeps on changing their run time, so you have to match versions. They have multi thread and non multithreaded, and using MFC and not using MFC, and link against DLLs and link to a static library, debug and non debug -- there are too many options when what we really want to do is make a single (gigantic) "lib" that other people can use seamlessly.

Case in point: the dreaded LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library message that pops out when you go to use someone else's library. What it means is that some compiler setting that most people don't care about at all is set one way in the library and another way in your own code. Microsoft's advice ('use /NODEFAULTLIB') is useless.

What often works for me is the /VERBOSE:LIB switch (which you have to type in yourself). It lets you see exactly what libraries are being pulled in; from that list you can (generally) tell what has to be updated.