Thursday, December 21, 2006

Microsoft treachery - C 6.0 versus C/C++ 7.0

Microsoft's C 6.0 compiler was the last version to support OS/2. They never offered a C++ compiler that supported generating OS/2 apps. That's fine, I understand that.

However, it seems they took measures in their C 7.0 product (and subsequent 16 bit compilers like VC 1.52) to actively thwart anyone who might try to use C 7.0 as a replacement raw code generator. IOW, keep using the C 6.0 headers, libraries, startup code, and linker, but use C 7.0 compiler to generate linkable OBJ's.

How did they do this? Well, it seems the C 7.0 compiler altered the way it emits CodeView debug information. One would think this might not be a problem -- just tell the thing to not produce debug info and barge ahead right?

WRONG - even when you tell it to omit debug infos it STILL emits some SEGDEF records for the "special" segments they hide CV information in(even though the segments are zero length). The problem is that the new SEGDEF records are SEGDEF32 records rather than the SEGDEF16 records that C 6.0 emitted.

Why this change to a 32 bit segment record for a product that is still fundamentally a 16 bit compiler? Why even emit it when there is no debug infos called for?

The most plausible explanation, so far, would appear to be that the 16 bit OS/2 linker that came with C 6.0 does not understand that record type and won't link C 7.0 generated .OBJ's rendering the 16 bit C 7.0, Visual C++ etc OBJ's unlinkable under any circumstances in an OS/2 environment. OS/2 of course was "the enemy" at that point in time.

Clever. Obscure. Treacherous. The majority of programmers who might want to do compiler mix-n-matching in projects trying to integrate blobs of code from many different languages would be stopped dead in their tracks by this trick.

Microsoft motto: "any color you like as long as its black"

Well BillG, you can lick my salty balls -- the gig is up. The .OBJ hacking app I've been working on now has the ability to repair this treachery and can transmute those SEGDEF32's into SEGDEF16's (and morph the similarly destructive LLNAMES record the C 6.0 linker doesn't understand into an LNAMES as well) and emit an altered .OBJ that can be used with the C 6.0 tools and under OS/2.


Francis W. Porretto said...

Easier just to stick with C++ V6.0, especially since the "enhancements" in V7.0 are mostly proprietary extensions to the language that would lock the user into Windows target environments and Microsoft development products for good.

Purple Avenger said...

The C 7.0 compiler offered 386 code generation, albeit in 16 bit USE16 segments, and the optimizer got a few new optimizations. Ignoring all the Windows gunk, which can be turned off, it could be a better code generator.

6.0 doesn't do C++, its a plain ANSI compiler.