C99 VLA (=Variable Lengh Array) helper macros... / was: Re: C99 Features

Nathaniel McCallum npmccallum at redhat.com
Thu Jul 9 12:47:25 EDT 2015


On Thu, 2015-07-09 at 12:40 -0400, Roland Mainz wrote:
> 
> ----- Original Message -----
> > From: "Nathaniel McCallum" <npmccallum at redhat.com>
> > To: "Roland Mainz" <rmainz at redhat.com>, krbdev at mit.edu
> > Sent: Thursday, July 9, 2015 6:21:50 PM
> > Subject: Re: C99 VLA (=Variable Lengh Array) helper macros... / 
> > was: Re: C99 Features
> > 
> > On Thu, 2015-07-09 at 10:44 -0400, Roland Mainz wrote:
> > > 
> > > ----- Original Message -----
> > > > From: "Roland Mainz" <rmainz at redhat.com>
> > > > To: krbdev at mit.edu
> > > > Sent: Tuesday, July 7, 2015 6:33:01 PM
> > > > Subject: Re: C99 Features
> > > > 
> > > > 
> > > > 
> > > > ----- Original Message -----
> > > > > From: "Nathaniel McCallum" <npmccallum at redhat.com>
> > > > > To: krbdev at mit.edu
> > > > > Sent: Tuesday, June 16, 2015 3:06:39 AM
> > > > > Subject: C99 Features
> > > > > 
> > > > > It has been 16 years. GCC has had support for many C99 
> > > > > features
> > > > > for a
> > > > > LongTimeNowTM. Clang has had them since the beginning. Clang 
> > > > > also
> > > > > now
> > > > > has official Windows builds (as well as many other 
> > > > > platforms).
> > > > > 
> > > > > Of course, MSVC still lags behind. However, they have started
> > > > > implementing features, including the following since MSVC 
> > > > > 2013
> > > > > [1]:
> > > > >  * _Bool
> > > > >  * Compound literals
> > > > >  * Designated initializers
> > > > >  * Mixing declarations with code
> > > > > 
> > > > > MS has also implemented most of the C99 libraries[2] and has
> > > > > already
> > > > > announced complete support for the C99 standard library in 
> > > > > MSVC
> > > > > 2015[3]. One of the big elephants in the room is VLAs. MS is
> > > > > unlikely
> > > > > to ever support them. But, it is also MS's stated policy to 
> > > > > only
> > > > > incorporate C features that are required for C++[4]. I'm not 
> > > > > sure
> > > > > that
> > > > > MIT should hold back support for new C features because MS 
> > > > > only
> > > > > wants
> > > > > to ship a C++ compiler.
> > > > > 
> > > > > So how about it? Can MIT start using C99 features? Even a 
> > > > > subset
> > > > > of the
> > > > > features would be helpful. I particularly care about all the
> > > > > above C99
> > > > > features that MS implemented plus VLAs. The latter, in
> > > > > particular, can
> > > > > eliminate a lot of heap allocations.
> > > > 
> > > > 1. Using |bool| would be a very good idea because it allows a 
> > > > lot
> > > > of
> > > > optimizations with low optimizer settings. There is a possible 
> > > > risk
> > > > of
> > > > namespace clash with |krb5_boolean| so I suggest to use a new
> > > > define like
> > > > > krb5_std_bool| if we want it in public APIs (which we should 
> > > > > do
> > > > > (question
> > > > for myself... did the ISO C spec define a size for |bool| ?))
> > > > 2. IMHO we should use |restrict| where possible (e.g. crypto,
> > > > string-heavy
> > > > code etc.) to squeeze out some performance
> > > > 3. VLAs can be tricky, but usually aren't a big problem if used
> > > > with care
> > > > (I've been there with Solaris's OS/Net long ago and it was a 
> > > > *pain*
> > > > politically-wise and getting all tools fixed, but these should 
> > > > be
> > > > issues if
> > > > the past). Main issue is to define an upper per-allocation 
> > > > limit
> > > > which can
> > > > be allocated via VLAs and then switch to |malloc()| if the
> > > > allocation is
> > > > larger than that limit (typically |getpagesize()*8| was 
> > > > considered
> > > > a "safe"
> > > > limit in Solaris OS/Net). If I recall it correctly the 
> > > > following
> > > > code should
> > > > handle the issues correctly (except that it should use the ISO 
> > > > C99
> > > > feature
> > > > test macros to test whether VLAs are available (this will cover 
> > > > the
> > > > "limitations" of the Microsoft compiler)):
> > > > -- snip --
> > > [snip]
> > > > -- snip --
> > > 
> > > Attached (as "vla.c.txt") is an updated version which fixes the
> > > reported issues:
> > > - Added support to compile with pre-C99 compilers
> > > - Added support for C11 VLA feature test macro |__STDC_NO_VLA__|
> > > - Fix multiple evaluations of the |size| argument in
> > > > VLA_ALLOC_ALLOCATE()|
> > > - Make testcase more troublesome for compilers and valgrind
> > > - Add more comments how stuff works
> > > - Attach code instead of pasting it inline to prevent the WebMail
> > > software from messing with the code
> > 
> > If you have to free the VLA, you've just lost half the benefit. It
> > would be better to fall back on alloca().
> 
> We don't have to free the VLA, the |VLA_ALLOC_FREE()| macro is there 
> because (see code - http://mailman.mit.edu/pipermail/krbdev/attachmen
> ts/20150709/4ec3a6c8/attachment.txt) we fall-back to |malloc()| if 
> the requested size is "too large" (this guards against accidental 
> stack exhaustion by a single VLA allocation or malicious attempts to 
> access "random" memory areas beyond the stack space). We directly 
> call |free()| because if we get the memory from a VLA array the 
> pointer which tracks |malloc()|'ed memory is |NULL| and POSIX 
> |free()| handles |free(NULL);| as no-op (we could change this to |if 
> (__builtin_expect(memory_from_malloc, 0)) free(memory_from_malloc);| 
> for the sake of making it easier for the compiler's loop optimiser 
> (if loops are involved at the same C block level)). 

I understand. But it means that you have to call VLA_ALLOC_FREE() at
all. This should not happen.

> > But seriously, I'd prefer this discussion not get hung upon VLAs. I
> > like them. But I care about other C99isms like compound literals 
> > much
> > more.
> 
> Agreed.... and |restrict|&&co. (plus gcc's |__builtin_prefetch()| 
> (see https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#index
> -g_t_005f_005fbuiltin_005fprefetch-4067) for crypto code) are 
> interesting too.
> 
> ----
> 
> Bye,
> Roland
> 


More information about the krbdev mailing list