Microsoft, please support (at least a tiny bit of) C99
blog.reverberate.org
blog.reverberate.org
I know this is probably a losing battle, but I feel better at least being able to express my displeasure about the issue.
I'm sure this is true for C++ which has a crazily complex ABI for things like classes and exceptions. But is this really the case for plain C? (not in the Linux world AFAIK)
There are some minor catches:
1. If you want a .lib instead of a .dll, you have to make one yourself separately using a tool. Not a big deal, it's just that gcc does do it for you.
2. No debug symbols, because MSVC doesn't support DWARF/etc.
3. gcc guarantees 16-byte stack alignment on x86_32, but only with respect to the caller; MSVC does not, so the stack may not be aligned as gcc expects it. You can use -mpreferred-stack-boundary to make gcc expect it, or you can just explicitly align the stack, either with the gcc intrinsic (requires ~gcc 4.2) or a small assembly function.
There are probably a few others, but overall, it does work; cdecl is cdecl.
Only C++ doesn't work.
Gcc works and produces good code, unfortunately you have to deal with the disgrace that is MinGW and it doesn't integrate in Visual Studio. Most Windows developers I know care about Visual Studio integration.
The Intel compiler produces excellent code, it is C99 and Microsoft compatible, and it seaminglessly integrates with Visual Studio. Unfortunately, it's very expensive, I have never seen it used in production.
I still wish they would support a few very basic C99 features though.
I definitely agree that it would be much better if MS just supported those few features, which frankly don't seem that hard in the scheme of things. Makes me think that they see some advantage to them in not supporting it, although I'm not sure what that'd actually be.
(*) e.g because you don't know how to do so, you're not good enough to program it, the main maintainers don't agree or because the source is closed.
The tools used to build Windows, including compilers, are available as the free Windows Driver Kit (WDK): http://msdn.microsoft.com/en-us/windows/hardware/gg487428
Sometimes the compiler versions match those of the current Visual Studio release, but not always.
Disclaimer: I work at Microsoft and know some people on the C++ compiler team. These comments are purely speculative on my part.
C11 adds some non-optional features whch needs compiler support (alignment specifiers, type-generic selections, unicode literals, ...).
Do you really think vendors which don' care about C99 will suddenly jump to implement all mandatory C11 features?
Look at the C99 rationale:
The inability to declare arrays whose size is known only at execution time was often cited as a primary deterrent to using C as a numerical computing language.
That's also the main reason for the introduction of complex types and type-generic math functions.
It's not as if the C committee got together and thought "Hey, what can we do to piss off compiler writers?" - there was actual demand for these features!
Sure, it made language semantics messier (runtime evaluation of sizeof, introduction of variably-modified types restricted to block or prototype scope, magical macros for math functions - which has been fixed with C11, btw), but C99 is indeed a superior language than C90 for doing numerics.
In fact, we've de-facto had such a mechanism for decades, but it hasn't been codified anywhere, actually for some of the same reasons people don't appreciate VLAs, but it at least rests much more comfortably with the rest of the language.
At some point, you go from enhancing C to breaking it in the interests of a small minority (who apparently don't want to use Fortran?). VLAs are, if not over the line, right on it.
In fact, we've de-facto had such a mechanism for decades
Unfortunately, that's not the case. There are actually two primary use cases for VLAs:
1. Variable-length multi-dimensional array parameters:
// C99
double trace(size_t n, double mat[][n])
{
double sum = 0;
for(size_t i = 0; i < n; ++i)
sum += mat[i][i];
return sum;
}
/* C90 */
double trace(size_t n, double mat[])
{
double sum = 0;
size_t i = 0;
for(; i < n; ++i)
sum += mat[i * n + i];
return sum;
}
While this may not look like much of an improvement in simple cases, not having to manually emulate array subscription is quite convenient in more complex ones.2. Allocation of variably-sized objects with automatic storage duration. Some libc implementations provide alloca() for that purpose -- unfortunately, it has issues (see eg http://c-faq.com/malloc/alloca.glb.html ).
for (int i = 0; i < n; i++) { ... }
instead of int i;
for (i = 0; i < n; i++) { ... }