On Thu, May 9, 2013 at 1:55 PM, Chandler Carruth <span dir="ltr"><<a href="mailto:chandlerc@google.com" target="_blank">chandlerc@google.com</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr"><div class="im">On Thu, May 9, 2013 at 9:11 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br></div><div class="gmail_extra">
<div class="gmail_quote"><div class="im"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi!<div><br></div><div>C++1y adds support for arrays of runtime bound (ARBs) to the C++ language. These are basically a restricted form of VLA, which can only be used for stack variables, and to which sizeof/decltype/typedef/etc can't be applied (though we'll still support those constructs as a GNU extension). See <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3639.html" target="_blank">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3639.html</a> for details.</div>
<div><br></div><div>Under N3639, we are required to throw an exception if the array bound * sizeof(element) calculation overflows, or if the array bound is too small. We're also permitted to call the global operator new/operator delete to acquire storage for the array, if we so choose. VLA stack usage can be problematic in some circumstances (especially in heavily-threaded code), so this may be something we want to pursue. Therefore I'm proposing the following implementation approach: </div>
</blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><br></div><div>* Add a -farb-stack-limit=N command-line option to control the maximum stack memory which can be used by an ARB. If the ARB doesn't fit in this limit, we use heap allocation instead. By default, there is no limit.</div>
<div>* Add a -farb-heap-limit=N command-line option to control the maximum heap memory which can be used by an ARB. If the ARB doesn't fit in this limit, we call __cxa_throw_bad_array_length. By default, the limit is 0 (never use heap allocation).</div>
<div>* If the bound is erroneous (too small, multiplication overflows, beyond our limit), we call __cxa_throw_bad_array_length. To support old C++ ABI libraries, we emit a weak form of this in every TU which invokes it, and the weak form calls __builtin_trap().</div>
</blockquote><div><br></div></div><div>I really like the ability to automatically defer large allocations to the heap. I don't have any specific problems with your proposed interface or semantics, but I would really like to work with the GCC community to get agreement on the semantics and flag names here (the library routines and exception names should I suspect be handled via the ABI group). Too often we've have divergence between the two and had to paper over it with compatibility layers (-fcolor-diagnostics vs. -fdiagnostics-color ...).</div>
<div class="im">
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div>Does this seem reasonable? Would we want any part of this checking (for instance, the overflow check + trap) in C, or in C++-before-C++14? Maybe the flags should be -fvla-foo instead of -farb-foo?<br></div></blockquote>
<div><br></div></div><div>I think it would be very useful to allow (as an extension) applying these semantics to VLAs in other language modes. It would suggest:</div><div><br></div><div>1) It be clearly marked as an extension with flags to control it. I'm OK with default-on, but I suspect the better strategy is to make this opt-in.</div>
<div><br></div><div>2) I think opting into it should get you the *full* semantic model proposed: the crazy things you can do with VLAs that didn't make it into C++1y should become errors.</div></div></div>
</div>
</blockquote></div><br><div>Since C99 doesn't allow initializers for VLAs, if we enable this by default in C99 mode, then (unless people use the -fvla-* / -farb-* arguments) the only behavioral difference will be that they get a trap if the multiplication overflows or the array bound is zero (both of which are UB). Is that significant enough to require opt-in?</div>
<div><br></div><div>As an aside, we accept arrays with a constant zero length as a GNU extension, but in C++14 we're required to throw an exception if a dynamic array bound is zero. How should we handle that?</div>