IIRC, MSVC stubbornly refuses to add support for variable-length arrays (which AFAIK are required for full C99 support). I don't know if there's anything else on that list of C99 features that MSVC doesn't support yet.
> IIRC, MSVC stubbornly refuses to add support for variable-length arrays (which AFAIK are required for full C99 support).
You are correct that VLAs are mandatory for C99, but they turned out to be such a
bad idea that they are optional in C11 onwards.
> I don't know if there's anything else on that list of C99 features that MSVC doesn't support yet.
IIRC, MSVC's `snprintf` and friends are broken (returns incorrect values and/or interprets the size parameter incorrectly). I think all of the annexure K stuff is broken in MSVC.
I think VLAs were a very good idea and they were not made optional because somebody thought they were a bad idea, but simply to make C11 easier to implement. VLA can be dangerous when the size depends on external input an when implemented without stack probing.
The Linux kernel is a very different environment than user space; it has a very limited stack space (16 KiB IIRC), and the consequences of exceeding that are worse than in user space.
> Google has paid the development effort for the Linux kernel to get rid of all VLA occurrences.
IIRC, what they were really interested in getting rid of was not the normal VLA we're talking about, but something even more esoteric called VLAIS (variable length arrays in structures), which clang didn't support. See https://lwn.net/Articles/441018/ for a discussion about that.
I dunno how to probe the stack in standard C, and so I never used VLAs, nor allowed them because (I thought that) there was no way to determine if a VLA declaration would cause a stack overflow.
I find them very useful and they often make the code cleaner. A dynamic run-time bound for a buffer can also make the code safer. VLAs are only dangerous when implemented naively (allocated on the stack without stack probing).
>are only dangerous when implemented naively (allocated on the stack without stack probing).
That's how it's implemented in all the major compilers. Anyway, even a hypothetical heap-based implementation would be bad because there's no way to report allocation errors.
Interestingly, I've seen code that uses the flexible array member idiom with MSVC. I'm fairly certain I first saw this in the windows code base when I worked at MS, and I believe it may even be in some public headers somewhere. In order to compile on MSVC, the trick uses MemberName[0] or MemberName[1] rather than the standard MemberName[]. GCC and clang warn about this. I suspect it might have been a common idiom in pre-C99 days.
You are probably confusing flexible array members with VLA. Those are two completely different features. You are thinking about the one where last member of struct is an array and you adjust size based on malloc size when allocating struct. VLA feature allows you specifying arbitrary non constant expression when declaring local stack variables with array type. Something like:
// VLA
int foo(int n) {
int array[n];
}
// flexible array member
struct s { int n; double d[]; };
struct s s1 = malloc(sizeof (struct s) + (sizeof (double) 8));
Flexible array members were implemented a long time ago. The oldest Visual C++ I have at hand is 2005 and it already has them (although only in C mode).
> I suspect it might have been a common idiom in pre-C99 days.
There is a Blog from Raymond on this[1]. The TL;DR: is that zero length arrays and FAMs weren't legal until C99. Not sure where the support from MSVC factors in. But that's the story and AFAIK he's sticking too it.
IIRC, MSVC stubbornly refuses to add support for variable-length arrays (which AFAIK are required for full C99 support). I don't know if there's anything else on that list of C99 features that MSVC doesn't support yet.