4 ms·
The removal of variable-length arrays is the main thing from C99 I miss in C11 (though it seems compilers can continue to support them if they wish). Imo they'r
by mjn 14y ago
The removal of variable-length arrays is the main thing from C99 I miss in C11 (though it seems compilers can continue to support them if they wish). Imo they're fairly elegant in many scenarios, and without them, C programmers tend to make heavier use of magic #define'd array sizes in order to retain the notational convenience of auto arrays.
- simias 14y agoI write C for a living and I've never ever used that feature. I don't think I've seen it used outside of C99 tutorials as well. Can you give us a practical example of some code where variable-length arrays prove really useful?
- mjn 14y agoI've mostly used them in two cases: 1. Multidimensional arrays where the sizes are quasi-fixed but not known at compile time. Comes up in various kinds of grid-simulation code, for example. You could malloc() in this case, but then you lose the notational convenience of 2d arrays. 2. Refactoring code that uses #define'd constants, to take runtime instead of compile-time parameters. For example, a common first-pass to said grid-simulation code is to have some WIDTH and HEIGHT magic numbers, which you might later regret and want to make into command-line parameters. Refactoring is trivial if you have VLAs. It also seems cleaner (to me) semantically. I can see why, implementation-wise, classic C auto arrays required constant sizes. But from a slightly higher-level perspective, whether a variable is auto or not, and whether its size is a compile-time constant or not, feel like independent decisions. It feels particularly messy that you have different notation for arrays whose sizes are known at compile time; the syntactic sugar there has some rough edges. I also find it cleaner if explicit malloc()s are used only when something beyond boilerplate is going on, letting the compiler handle the boilerplate case of allocating/deallocating a conceptually block-scoped array of size N.
- jedbrown 14y agoI usually don't let them creep into the API, but I use them for convenience within a function that needs direct access to the multidimensional structure, i.e. void func(int M, int N, int P, double *a_flat) { double (*a)[N][P] = (double (*)[N][P])a_flat; // use a[i+1][j+2][k-1] instead of a_flat[((i+1)*N+(j+2))*P+k-1].
- binarycrusader 14y agoVariable-length arrays are great for printf-like functions.
- kevinnk 14y agoHow so? Do you mind giving an example of a printf like function that needs variable length arrays?
- binarycrusader 14y agoI wouldn't call it a "need", more like "occasionally desirable". The short version is that it's a convenient method of letting the compiler handle resource management when you have a variable number of values and sufficient stack space. As others pointed out, it's particularly handy for multi-dimensional arrays. There are also some possible applications here: http://gustedt.wordpress.com/2011/01/13/vla-as-function-arguments/ http://gustedt.wordpress.com/2011/01/13/vla-as-function-argu... In fairness, I've used them only rarely, but those few times I've used them have saved me a bit of grief. I could easily live without them if required...
- nitrogen 14y agoAre you perhaps thinking of variable length argument lists?
- binarycrusader 14y agoNot quite; those are handy too. Admittedly, varargs is more useful than vla, but vla can be useful for these functions as well.
- maximilianburke 14y agoHave they been removed? I thought they were just downgraded from a mandatory feature to an optional feature.
- mjn 14y agoTrue, I'm unclear on what precisely that means. C traditionally hasn't had subsetting, so "standard C" code is supposed to compile correctly on any conforming implementation. If your code is "standard C99", any conformant C99 compiler is supposed to compile it correctly; and otherwise, you can't assume that (for example, you may be consciously using a GCC extension, which is ok, or relying on implementation-defined behavior, which is usually bad). But if you write C11 that uses VLAs, it seems like it's still standard C11, sort of: VLAs aren't merely a vendor-specific extension, like the GCC extensions are, but an optional C11 feature which hasn't been deprecated. Nonetheless, a conforming C11 compiler doesn't have to accept your code, so in that sense your code isn't really "standard C11". Will there be more fine-grained names for the different subsets of the standard features, so you can say that such code is compliant with "maxi-C11" but not with "core C11" or something?
- cmccabe 14y agoThe issue with VLAs (variable length arrays) is that what tends to happen is that programmers create a denial-of-service bug. It's easy to do-- just create a VLA without first checking to make sure the size isn't too big. Then invalid (or sometimes even valid) input may lead you to use too much stack space, and-- boom! Segfault. These segfaults can be hard to reproduce because stack sizes can vary between machines or depending on which code path you call the function in. This is why Google banned VLAs in their coding standard. If you're absolutely sure that you can handle the power, you can always call alloca and get some stack-allocated space, even with ancient C compilers. Just make sure to enforce a reasonable upper limit. Also, never mix C99-style arrays and alloca.