John,
While I'm quite encouraged at the idea of making upgrades easier, it's not as simple a scenario as just picking a version of a DLL for naming reasons and sticking with it. The C# and Java suggestions are undoubtedly handy ones, and will make the lives of those deployments much easier.
You might find there will be issues with what you're wanting to achieve with C under Windows, especially if you're tying the Gen runtimes to one version and letting applications build at another (see this article Potential Errors Passing CRT Objects Across DLL Boundaries "Potential Errors Passing CRT Objects Across DLL Boundaries"). There'd need to be some fairly strict discipline as to what you and cannot do in the runtimes and objects passed between them. Additionally, at some point the version of Visual Studio you pick for the Gen runtimes will go out of support - especially as Microsoft move to near yearly releases of their compiler and tooling.
The bigger issue, I would argue, isn't the cost of regenerating and recompiling - while these are time consuming processes, they're not inordinately difficult to achieve, and there are processes customers can use to simplify and streamline this. The real issue is application level changes caused by runtime behavioural changes. Some of the functions you implement for the user change between release - and thus, even if I could just drop a new set of runtimes in, I don't have a simple upgrade.
Take VERIFY, for example. Its behaviour changed at Gen 6, Gen 8.0, twice at Gen 8.0 IE1 and at Gen 8.5. The effective behaviour of this function changed between releases. So even if a customer dropped in new, compatible linkage runtimes, they'll still have to do a potential significant regression retest of their application stack, once they have find and isolated all incidents of where this function has occurred. While it's perhaps the most obvious example, it isn't the only one (MAKE ERROR, JULDATE, SUBSTRDBCS, etc.).
Given that, I would argue you have a separate versioning issue at that point. To be able to upgrade swiftly and drop in new runtimes would mean that a user would have to be able to rely on the application behaving as it already does in a consistent, predictable fashion. So if you change VERIFY again, you can't update the existing implementation - you'd have to call it VERIFY2, VERIFYEX or similar, so that a customer can opt in to the new behaviour as and when they rebuild/modify their application, rather than being forced into a path of significant retest. For functions and the like, this wouldn't be a particularly burdensome thing (though the practicalities of re-clicking all VERIFY statements would be a frustration). But where you change things like DISABLED BY or MAKE ERROR statements, that's a harder one, as introducing new language constructs isn't great.
I guess my point is this - you can solve the technical challenge of versioning the runtimes, and I don't suspect it's overtly difficult to achieve. However, upgrades aren't just about upgrading tool chains, but ensuring the user's built applications don't change behaviour just because of an upgrade. And as long as function behaviour and statement behaviour can change because of a runtime upgrade, this won't simplify a customer's upgrade path in any really significant way.
And that's just Windows, not the other supported platforms. I'm sure they have their own challenges too.