-
unsigned int data_size = 32;
unsigned char data[data_size];
unsigned int sense_len = 256;
unsigned char sense[sense_len];
This code doesn't compile on a couple of C compilers { SierraCC, Avget68kCC, AtlasMIPSCC, ... }
It works on Gcc -v4.1.2 ... Gcc -v11.0
isn't bad idea to define the size of array this way?
-
It is not a bad idea at all since you don't have to clean it up afterwards / use dynamic memory allocation. However this wasn't in the original C specification so some compiler may not support it with the default settings. Check the manuals & command line options that have to do with what C standard the compiler is set to.
-
https://www.geeksforgeeks.org/variable-length-arrays-in-c-and-c/ (https://www.geeksforgeeks.org/variable-length-arrays-in-c-and-c/)
-
It is not a bad idea at all since you don't have to clean it up afterwards / use dynamic memory allocation.
I prefer this approach
#define data_SIZE xxxx
data_t data[data_SIZE];
size_t data_size = data_SIZE;
this way, it works on all my C compilers, including the old one used by IDT for their MIPSR2K prototypes (~1995).
-
It is not a bad idea at all since you don't have to clean it up afterwards / use dynamic memory allocation.
I prefer this approach
#define data_SIZE xxxx
data_t data[data_SIZE];
size_t data_size = data_SIZE;
this way, it works on all my C compilers, including the old one used by IDT for their MIPSR2K prototypes (~1995).
You know that you could have made the size initializer a constant ? :palm:
-
Variable length arrays are a problem for my ICEs because they don't understand the size, especially when the array size depends on a function parameter
void fun(int n)
{
int arr[n]; // <--------- the ICE here thinks WTF?!? is the size of arr?!?
// ......
}
int main()
{
fun(6);
}
Gcc v4.1.2 is very old and does not complain, while the above code does nothing but trigger errors on both the C compiler and ICE with the code completely rejected!
runtime sized array are bad for automated ICE-debugging, at least for me :-//
-
You know that you could have made the size initializer a constant ? :palm:
umm, yeah, at least Gcc triggers warnings and errors if you try to modify something defined as constant ... it's just that the keyworkd "const" is ignored by my ICE, so making the size of the initializer a constant is useful like sweeping leaves on the street on a windy day :-//
-
const unsigned int data_size = 32;
unsigned char data[data_size];
const unsigned int sense_len = 256;
unsigned char sense[sense_len];
Now it will.
-
Only C++ constexpr can be used to specify array dimensions. The usual C solution is #define.
Inside function scope a VLA will be created and then data_size doesn't need to be const, you could even use atoi(argv[1]) instead. If this doesn't work then your compiler isn't C99 compliant.
VLAs consume stack space :--
-
I don't even understand how the code you posted compiles with GCC.
I tried both with GCC 10.3 and GCC 12, and it fails in both cases with an error: "variably modified 'data' at file scope".
But of course you need to put context here.
If the code you posted is at file scope (global context), then it's an error even in C99+.
If it's in local scope, then it's a VLA, and is only supported by a C99+-compliant compiler. If that's what you were doing, I suppose the compilers you mention are not compliant with C99.
And yes, as I think was mentioned about VLAs not too long ago, even with a const qualifier for the size variable in local scope, this will yield a VLA. That's just C. If you don't want VLAs, just use a macro. You have no choice.
-
C is a bit more limited than C++ with respect to dimensioning arrays.
You can create a VLA ( Variable-length array ) with dynamic size, or you can create
an array of either zero (special cases) or fixed dimensions.
Er... That makes C a bit less limited with respect to dimensioning arrays. Less, not more. C++ is more limited, since C++ does not support VLA.
It is perhaps unfortunate that one can't use an expression which involves a static or global const variable whose constant initializer value is known to the compiler at the time of the array definition to also dimension the array by a shared indirect "constant" expression value.
It is completely not clear what it is supposed to mean. Yes, you can do all that as long as your C compiler supports VLA and the array is local.
In C++ one can use constexpr values as array dimensions more freely than the plain "const" values which are comparable in both C and C++.
That is completely incorrect. `const` values are very different in C and C++.
`constexpr` variables do not add anything over `const` in C++. They simply help user to express their intent (and the compiler to enforce that intent).
-
VLAs consume stack space :--
All local arrays and all local variables consume stack space. VLA does not stand out in any way, unless you do something really stupid.
Are local variables :-- ?
-
Local arrays are unique in being stack allocated AND having the potential to eat up a lot of space, which is often in short supply in places where C is used. Even Linux processes are limited to 8MB stack by default.
(Also, local variables can exist solely in CPU registers ;))
-
This discussion about VLAs is potentially endless a bit like the one about electricity. :-DD
As TheCalligrapher just said, there is no difference with any other object allocated on the stack.
The only difference, sure, is that VLAs can potentially eat up a lot of stack space if the programmer doesn't know what they are doing. In which case, they can do a lot of damage elsewhere too. Again yet another endless "discussion" about C in general, I guess.
You're assuming VLAs are "bad" because they can allocate "too much space" on the stack, but it's like seeing only one side of things while ignoring the rest.
Indeed, OTOH, a potential benefit of VLAs is precisely that you don't need to allocate a fixed-size array (and thus with the max size required in all cases) on the stack in a given context, but can allocate what is just necessary at run-time, actually yielding a more reasoned use of stack space.
-
Although you're initializating the variable, it's still a ram variable, could change anytime, that's what the compiler sees, while value of a variable declaration must be constant.
Options are this:
const unsigned int data_size = 32;
unsigned char data[data_size];
const unsigned int sense_len = 256;
unsigned char sense[sense_len];
Or:
#define data_size 32
unsigned char data[data_size];
#define sense_len 256
unsigned char sense[sense_len];
-
Although you're initializating the variable, it's still a ram variable, could change anytime, that's what the compiler sees, while value of a variable declaration must be constant.
Options are this:
const unsigned int data_size = 32;
unsigned char data[data_size];
const unsigned int sense_len = 256;
unsigned char sense[sense_len];
According to the post above yours, this is not valid in C if the array size needs to be statically defined at compile time. The one with #define is OK, though.
-
Why? Size is declared as const. The compiler knows that.
It compiles right away without any warning.
In the instant you remove const - error!
-
It appears some compilers behave non-standard when given an const integer as array declarator expression.
I don't remember ever hitting this, but apparently the pure environment of godbolt does show it.
Looks like if you don't want to use the preprocessor you can use enums.
-
It appears some compilers behave non-standard when given an const integer as array declarator expression.
Yup, precisely. AvgetCC is an example.
Also my ICE doesn't correctly understand "const", hence its parser is set to ignore (skip token).
I don't use "const" in none of my projects.
Even if you look at the source code of big and complex projects like the firmware of my industrial embroidery machine, you won't find any "const".
"const" is banned from my C-coding style, and I tend to use the linker_script to specifically allocate constant variables in the RO session, hence again, I don't need "const".
---
Anyway, yesterday I rewrote the whole C source in a clean way.
No more "const", no more "VLA". Thins are clean, debugged through an automatic test-case plan, all is fine like it should be.
For me: VLA is banned from my C-coding style.
( I am a weird C programmer, I know :o :o :o )
-
Have a look at the below link;
it fails with an error on gcc, though clang passes it with a warning that it allowed it as an extension:
https://godbolt.org/z/3fPhnhYTz
That is a handy site because one can easily try most common compilers / platforms / compilation options and see what
a snipped of code compiles to or if it compiles without errors / warnings at all.
That's for a static storage version of your suggested 'const' code.
If the storage wasn't specified to be static then the 'const' wouldn't matter since
one can create VLAs even with dynamic lengths no problem so of course a const dimension would also have worked
to create a VLA. So if that's the aim then no problem. But it isn't a general solution for creating
truly 'const' global / extern / static data arrays of constant dimension and initialization such as one
could commonly have linked to be placed in FLASH / ROM / RODATA etc. instead of living on the RAM stack.
Don't use "static", then. VLA's cannot be static. They're then not on the stack but in the BSS or DATA segment and that just cannot work.
-
...
"const" is banned from my C-coding style, and I tend to use the linker_script to specifically allocate constant variables in the RO session, hence again, I don't need "const".
...
const should still be used to indicate design intent. It will still function as operator that values are immutable, which is valueable in my opinion.
For example, both variants of const pointers (const ptr and ptr to const), and factors for calculations should be const.
It also enforces types on your values, define does not. Something to aware of.
-
Why? Size is declared as const. The compiler knows that.
It compiles right away without any warning.
In the instant you remove const - error!
Well, simply because that's not C - if the declaration has static storage duration (e.g. file scope).
If the compiler swallows it without complaining, then it's not being used as a C compiler.
See C11, 6.7.6.2, ยง2.
That the const value of the int is known at compile time is immaterial, that's not the way the language is defined:
gcc and clang will by default compile a language which is "almost, but not quite, entirely unlike C" (cit.).
If you want to coax them to be C compilers, -std=C11 -Wall -Wextra -pedantic is needed (for C11 - change to your favourite flavour).
But rejoice, it's still valid C++! Though there are no VLA in C++, and const semantic is slightly different.
-
And, as already pointed out here and in other threads, in C99+, using a variable as size in the declaration of an array is forbidden in file scope (so non-local context), and makes the array a VLA de-facto in local context, whether the variable itself is qualified const or not. Doesn't matter.
That said, as I think I also showed in another thread, if optimizations are enabled and the compiler is not brain-dead, if the value of said variable is effectively a constant in its scope (whether it's qualified const or not), then the actual compiled code will be that of a regular array and not that of a VLA. Now disable optimizations, and you'll get code for a VLA even when the size variable is statically analyzed as being constant in its scope. And compiled as a VLA means significant overhead manipulating the stack. But just see for yourself looking at assembly code and trying various code combinations and optimization levels.
-
But just see for yourself looking at assembly code and trying various code combinations and optimization levels.
Or just write C - for me, at least, it's easier: as opposed to the compilateur du jour, the standard stays mostly put, and compliance of the usual suspects is pretty good, when dutifully instructed.
I rewrote the whole C source in a clean way.
No more "const",
I think you misspelled "less safe" - I know, I know, your ICE will melt if you use const. ::)
-
I think you misspelled "less safe"
Our ICE better understands _RO suffix in the variable name, so it can be checked automatically and without the need to query for the definition. It requires less memory in the local ICE database, is literally one less token, generates fewer queries between the ICE and the host, and is easier for both the local AI and the human operator to check than a distant word "const" which no one, except the C(1) compiler, will examine.
(1) sometimes misunderstanding it, like AvogetCC does. Incredible that we paid ~6K euros for it in 2001, and Off course, VLA is not supported.
-
It appears some compilers behave non-standard when given an const integer as array declarator expression.
I don't remember ever hitting this, but apparently the pure environment of godbolt does show it.
What exactly do you refer to as "non-standard" here?
-
Aha, nice to know. Anyways I always used defines for that :-+
-
It appears some compilers behave non-standard when given an const integer as array declarator expression.
I don't remember ever hitting this, but apparently the pure environment of godbolt does show it.
What exactly do you refer to as "non-standard" here?
Technically const int size = 50; isn't an "Integer constant expression" valid for use in the array declarator. But some compilers allow it, because why shouldn't it be possible, it's not changing anyway, so it can derive the value. After all, there is a valid integer constant expression literal being used, but just one reference away.
Then when you run the compiler with strict rules by specifying (https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html)the standard it should follow, it says that it can't allow it. Which is technically correct, the best kind of correct. :P
C is amazing, but it also is made by humans, so there will be corner (http://blog.httrack.com/blog/2014/05/30/c-corner-cases-and-funny-things/)cases, also extensions (https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html)!.
-
It appears some compilers behave non-standard when given an const integer as array declarator expression.
I don't remember ever hitting this, but apparently the pure environment of godbolt does show it.
What exactly do you refer to as "non-standard" here?
Technically const int size = 50; isn't an "Integer constant expression" valid for use in the array declarator.
True. In C it is not an Integer Constant Expression, in C++ it is an Integer Constant Expression.
But some compilers allow it, because why shouldn't it be possible, it's not changing anyway, so it can derive the value.
Um... Some C compilers allow it because they support VLA. An array with const int size is perfectly standard in C, as long as it is recognized as a VLA by the compiler and behaves as a VLA afterwards. Nothing non-standard about it.
After all, there is a valid integer constant expression literal being used, but just one reference away.
Not really. They simply treat it as a VLA. Basically, they ignore the const, they don't care about the constant expression hiding behind the name.
Then when you run the compiler with strict rules by specifying (https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html)the standard it should follow, it says that it can't allow it. Which is technically correct, the best kind of correct. :P
If you specify a pre-C99 standard, then of course. There was no VLA before C99.
-
But some compilers allow it, because why shouldn't it be possible, it's not changing anyway, so it can derive the value.
Um... Some C compilers allow it because they support VLA. An array with const int size is perfectly standard in C, as long as it is recognized as a VLA by the compiler and behaves as a VLA afterwards. Nothing non-standard about it.
Yep. Seems it has a hard time sinking in even though we said it several times already. ::)
-
Well, I disagree about a static storage duration array declared with a const int as dimension (or some equivalent expression) being a VLA in any way.
From the C standard perspective, it's not: static storage duration VLA being explicitly forbidden by the standard it's a non-entity.
OTOH, from an extension point of view, the array will have a constant, non changeable size, so no VLA semantic in any way.
On the gripping hand, I would rather surmise that the compilers allowing such construct are not relaxing VLA constraints, but rather taking advantage of paragraph 10 of ch 6.6 Constant Expressions:
An implementation may accept other forms of constant expressions.
-
Sometimes, it's like talking with a lawyer :o :o :o
You don't understand legalese, but you hope that paying someone who talks strangely solves your problems somehow.
-
On the gripping hand, I would rather surmise that the compilers allowing such construct are not relaxing VLA constraints, but rather taking advantage of paragraph 10 of ch 6.6 Constant Expressions:
An implementation may accept other forms of constant expressions.
So mote it be.
-
Well, I disagree about a static storage duration array declared with a const int as dimension (or some equivalent expression) being a VLA in any way.
And as often, it's running in circles. ;D
As was noted early in the thread, with the OP's example, there was no way it could have been anything else than VLAs IMO, since 1/ the arrays were not qualified static and 2/ even if context was not given, as I mentioned earlier, it couldn't have been in file scope (so arrays declared as global variables), because the OP mentioned that it would compile with GCC, and no version of GCC I tried (but sure haven't tried them all) supports that.
So yes, sure, as I also said earlier, in "file scope", this construct is illegal in std C, and if some compiler accepts it, then it sure must be as an extension. But I have yet to find a compiler that does (and again, the little the OP gave us doesn't really point us to that case). Could you point me to one? Or did I miss something with GCC?
-
I am not disagreeing with you - if not on some fine points, brought up just to gently mock DiTBho >:D!
As for the compiler, clang will warn you, but still compile that code, unless one uses -Werror.
-
mentioned that it would compile with GCC
I tried the original code with Gcc v4.1.2 on a PowerPC-7410 machine, got compiled and worked correctly :o :o :o
A patch may have been applied to Gcc, I cannot verify it.
-
mentioned that it would compile with GCC
I tried the original code with Gcc v4.1.2 on a PowerPC-7410 machine, got compiled and worked correctly :o :o :o
A patch may have been applied to Gcc, I cannot verify it.
So I suppose your declarations were at file scope? (Because it's still not 100% clear from what you said.)
GCC's default behavior keeps changing from version to version, so some extensions may have been added/removed/enabled by default or not/ depending on version.
The only way of ensuring something relatively consistent is to pass a 'std=' option to GCC. (Not completely foolproof, but better than leaving the default behavior.)
So anyway, I suggest not using variables for declaring fixed-size arrays in C, even if said variable is qualified const. It may "compile" depending on context and compiler extensions, but it's not guaranteed, not necessarily standard except in local context, and in this latter case, will yield a VLA that you didn't necessarily expect. It may look nicer than macros, but it's just not the right way of doing it in std C (unless in local context as auto variables and you really want a VLA.)
People not liking macros just need to get over it when writing C. Insisting on avoiding them will usually lead to writing non-standard C, and/or use hard-coded values everywhere, and/or duplicate code, making your code a hell to maintain. Just MHO.
-
To give you the point, I found the original code on a PowerMac-clone running GNU/Linux ~2007. I also found a couple of programs written by a dude to query the installed PCI-SCSI-HBA.
Interesting code, but it's written, as usual, in a very dirty way, and I am going to study and rewrite from scratch in order to integrate its functionalities into my last toil.
as an extension
On the GNU/Linux (ext2, OMG) partition there is a Gcc v4.1.2 compiler, enabled_languages are {C, C++ }.
When the 'Makefile' invokes 'Gcc', 'CC1' is perfectly able to compile the dirty code, even if there are no explicit Cflags passed to the compiler.
is it implicit C99? Or what? Dunno :-//
How can I check if it has been patched and / or compiled with extensions? :o :o :o
-
People not liking macros just need to get over it when writing C. Insisting on avoiding them will usually lead to writing non-standard C
I think this refers to what I said in the other topic, when I said that I don't like Macros :o :o :o
Well, Macros are the result of a #define statement, and the pre-processor is a feature of C.
Therefore, technically, the following is a Macro:
#define array_SIZE 1024
uint8_t array[ array_SIZE ];
however, it's the only exception to what I suggested to avoid in the other topic and I still strongly suggest: to avoid all other (ab)uses of the pre-processor.
That is when and why:
1) affect things you don't realize, and you can not debug
2) expansion can lead to strange side effects
3) your code gets deranged-replacements, and your CC/ICE leads to strange error WTF?-messages
-
So I suppose your declarations were at file scope? (Because it's still not 100% clear from what you said.)
In the original C file, there is only one single .c file with no .h files.
One file, one program, and at some point, you read
const unsigned int data_size = 32;
unsigned char data[data_size];
const unsigned int sense_len = 256;
unsigned char sense[sense_len];
as global definition, outside a function.
It immediately compiled as is with gcc v4.1.2. When I removed "const" still the code got compiled, and in both cases it worked correctly.
Great! But when I moved the code to AvogetCC, it didn't get compiled at all. The compiler doesn't understand VLAs (there are 21 points to be rewritten), and doesn't like 'const', and this is also a problem for my ICE since I massively need to debug/interact with the hardware.
I need to use AvogetCC + ICE on a industrial PPC machine with the same HBA chip soldered on the Motherboard but exposed to a simpler bus, I am doing it for wild hacking reasons (full reverse engineering of the used SCSI queries), I cannot use Gcc because it's not a GNU-supported machine (NetBSD .. maybe on day it will run, but at the moment the kernel crashes), hence here we go rewriting everything.
Problem solved two days ago, just ... still questions in my head + tons of WTF?!? :o :o :o
-
In the original C file, there is only one single .c file with no .h files.
One file, one program, and at some point, you read
const unsigned int data_size = 32;
unsigned char data[data_size];
const unsigned int sense_len = 256;
unsigned char sense[sense_len];
as global definition, outside a function.
It immediately compiled as is with gcc v4.1.2. When I removed "const" still the code got compiled, and in both cases it worked correctly.
This is very confusing, because see here:
https://godbolt.org/z/ernG9531s
It really didn't ought to compile.
-
So I suppose your declarations were at file scope? (Because it's still not 100% clear from what you said.)
In the original C file, there is only one single .c file with no .h files.
One file, one program, and at some point, you read
const unsigned int data_size = 32;
unsigned char data[data_size];
const unsigned int sense_len = 256;
unsigned char sense[sense_len];
as global definition, outside a function.
OK, so indeed at what is called "file scope".
It immediately compiled as is with gcc v4.1.2. When I removed "const" still the code got compiled, and in both cases it worked correctly.
I don't get how. Tried is with GCC 4.1.2 on godbolt, we get the same error "error: variably modified 'data' at file scope".
Possibly the compiler you were using was patched or something. But with the official source code, it yields an error.
Great! But when I moved the code to AvogetCC, it didn't get compiled at all. The compiler doesn't understand VLAs (there are 21 points to be rewritten), and doesn't like 'const',
If it doesn't "understand" VLAs, then it's just not compliant with C99. That's the only thing that will tell you if VLAs are supported. (Note that with later versions of the C std, VLAs became optional IIRC. But from what I get, you seem to be using rather old tools, so the probability of your compilers not compliant with C99 is much higher than that of being compliant with later revisions of the std and making it default.)
That said, again in this global context ("file scope"), the above construct is NOT a VLA. It's nothing. It's just not allowed in C. Some compilers may allow it as an extension, but GCC does not, with all tests I've done with versions down to 4.1.2. (Or maybe it would require an extra option I'm not aware of.) So if yours does, either it was patched for this, or enabled some compiler option that I do not know.
-
Not easy on a 2022 portage because there is this constraint that doesn't allow you to easily compile anything <Gcc-v10
# 2022-05-28: GCC v9 and older no longer receive upstream support or fixes for bugs.
# Please switch to a newer GCC version using gcc-config.
# The lowest supported version of GCC is GCC 10.
<sys-devel/gcc-10
(plus, they removed all the building eclass support ... and, off course, the new ones are incompatible with the old one)
but, thanks to a combined chrooted-old-rootfs, I recreated gcc v4.1.2 on a modern Gentoo machine with all the old Gentoo patches
results:
gcc test.c -o test
gcc-v4.1.2, PPC7450, 32bit/BE
test.c:2: error: variably modified 'data' at file scope
test.c:4: error: variably modified 'sense' at file scope
gcc-v9.4.0, PPC7450, 32bit/BE
test.c:2:15: error: variably modified 'data' at file scope
2 | unsigned char data[data_size];
| ^~~~
test.c:4:15: error: variably modified 'sense' at file scope
4 | unsigned char sense[sense_len];
| ^~~~~
Perfect! So it doesn't compile unless you apply a special patch, which now I know, it was officially supported by neither GNU nor Gentoo.
/* test.c */
const unsigned int data_size = 32;
unsigned char data[data_size];
const unsigned int sense_len = 256;
unsigned char sense[sense_len];
int main()
{
return 0;
}
Where did the patch come from? Who did applied it? And why? ... It's a mystery ... :-//
Thanks guys!
-
Note that with later versions of the C std, VLAs became optional IIRC.
Yes, in C11 the macro __STDC_NO_VLA__ is defined (to 1) to indicate that there's no support for VLA and VM types (types depending on a VLA, to simplify), see 6.10.8.3 Conditional feature macros:
[...]
__STDC_NO_VLA__ The integer constant 1, intended to indicate that the implementation does not support variable length arrays or variably modified types.
Note that this is going (probably) to change again in C23 (https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2992.pdf), where VM types will be mandatory, as well as VLA with allocated storage duration, i.e. a VLA one gets through setting a VLA pointer - a VM type - to an address returned by malloc(), and VLA syntax for function paramter (this last one is a good thing, if I understand the implications correctly).
-
void foo()
{
const unsigned int data_size = 32;
unsigned char data[data_size];
const unsigned int sense_len = 256;
unsigned char sense[sense_len];
}
int main()
{
foo();
return 0;
}
for completeness, I repeated the test: this compiles on Gcc v4.1.2, doesn't compile on AvogetCC
-
Note that this is going (probably) to change again in C23 (https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2992.pdf), where VM types will be mandatory, as well as VLA with allocated storage duration
There are two modules in modern Firefox that require VLA; I didn't look at the code, but I am 100% sure because I remember a patch that didn't nothing but enable them with a define. Hope they don't mess too much, it's already a mess supporting Firefox, especially on ancient machines where you cannot always have the latest compier feature on hand.
-
void foo()
{
const unsigned int data_size = 32;
unsigned char data[data_size];
const unsigned int sense_len = 256;
unsigned char sense[sense_len];
}
int main()
{
foo();
return 0;
}
for completeness, I repeated the test: this compiles on Gcc v4.1.2, doesn't compile on AvogetCC
But in this context (local scope, auto), those are VLAs, so again, your AvogetCC is not C99-compliant, and that's it.
-
Note that this is going (probably) to change again in C23 (https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2992.pdf), where VM types will be mandatory, as well as VLA with allocated storage duration
There are two modules in modern Firefox that require VLA; I didn't look at the code, but I am 100% sure because I remember a patch that didn't nothing but enable them with a define. Hope they don't mess too much, it's already a mess supporting Firefox, especially on ancient machines where you cannot always have the latest compier feature on hand.
Just because VLAs became optional in C11 doesn't mean that compilers will stop supporting them. It means they might. If that's convenient for them. Also, it doesn't mean they will stop supporting C99 either.
There's absolutely 0 chance IMHO that GCC or CLang would stop supporting VLAs even with newer revisions of the std, but even less chance they will stop supporting C99, so there will always be at least an option to force C99.
For more obscure compilers, all bets are off.
-
You can always make your own VLA by recursion!
please dont