[RFC] [PATCH] Add __array_size keyword

Stuart Brady sdb-gcc@zubnet.me.uk
Sat Feb 13 03:17:00 GMT 2016

On Thu, Feb 11, 2016 at 10:41:02PM +0000, Joseph Myers wrote:
> For proposed features, I find documentation and testcases of much more 
> value than the rest of the implementation.

I can see the logic of that.  This is the part that I find a little
tricky, so please bear with me here.

> Critical issues to define and cover thoroughly in tests include the
> rules for when operands of sizeof are evaluated, as adapted
> appropriately for this keyword, and for when it returns various kinds
> of constants.

So in other words, adapting all of the sizeof tests would be appropriate,
and sizeof tests for non-array types would change from expected passes to
expected failures?

> Is the rule for your keyword that the operand is evaluated, and the
> result not an integer constant, iff the operand is an array with a
> variable number of elements (as opposed to an array with a constant
> number of elements that themselves are variable-sized, for example)?

If I've understood correctly, then yes:

   #include <stdio.h>
   void foo(int i) {
     int a[i], b[__array_size(a)];
     printf("%zi, %zi\n", __array_size(a), __array_size(b));
   int main() { foo(42); }

This will print "42, 42".

> C11 (sizeof) would need testing, 

Does this section differ from the September 7th draft in any way?

Perhaps I should draw up an equivalent specification for __array_size
based on, only I'm unsure if it would be legal for me to do that?

> but so would 6.9#3 (rules about when declared identifiers need to be 
> defined), and 6.6#6 and #8 (constant expressions) - and anything else in 
> C11 that mentions sizeof.

Well, there are some mentions of sizeof such as those in connection with
offsetof where I do not think any tests or documentation would be needed
but yes, tests would be needed for equivalent behaviour with __array_size
instead of sizeof, for those sections which you mention.

> Presumably this keyword can be applied to an array at function prototype
> scope whose size is explicitly or implicitly [*], though nothing useful
> can be done with the results, as with [*]? (Cf. gcc.dg/vla-5.c.)

I'm not sure I quite understand the meaning of an implicit [*].  Does that
just mean __array_size(foo) with an int foo[*] as another parameter?

I have realised that my patch has problems in this area, which I will
fix, but it still makes sense to me to document the desired functionality
and test cases, so I shall continue along this path.

As a brief aside, I do get an ICE with the following source, without any
modifications of my own:

   int bar() { return foo(); }
   void baz(int c[foo()]) { return; }

I will look into submitting a PR for this properly soon, but will not
mind if someone wants to take this task upon themselves instead,
especially as we are into the release phase for GCC 6 and this may be
an issue worth fixing.  (Note that Debian's GCC 5.3.1 is also affected.)

For a hypothetical change to the C standard itself, I think one might use
the name "_ArraySize", but for a non-standard extension this would not be
appropriate.  I think "__array_size" is fine, though, and is consistent
with "__alignof".

Here's a list of places in the standard that reference sizeof, and the
changes that would need to be made to the standard if this keyword were
to become part of it (using the "wrong" name of __array_size): 43) no change no change
          #3: extended to include __array_size
          #4: no change
   6.4.1#1: add __array_size to keyword list
   6.5.3#1: add __array_size unary-expression,
            and __array_size ( type-name ) duplicate the entire section, with considerable changes:
          #1: "shall only be applied to an expression that has array
              type or to the parenthesized name of such a type"
          #2: "yields the number of elements in the array"
          #3: remove entirely
          #5: remove entirely, or provide example using calloc()
          #6: remove entirely, also update original?
          #7: update appropriately
          88) remove?
   6.6#6: extend to include __array_size (both occurrences)
          98) update
      #8: extend to include __array_size (both occurrences)
   6.7.1 103) "only operators [...] are sizeof and __array_size" no change
          #18: no change
          #19: no change
          #20: no change
          #21: no change
          #22: no change no change extend to include __array_size
   6.9#3: extend to include __array_size
   6.9#5: extend to include __array_size no change
   7.17#2: extend to include __array_size
   A.1.2: add __array_size to keyword list
   A.2.1: add __array_size unary-expression,
          and __array_size ( type-name )
   J.1: extend to include __array_size
   J.2: extend to include __array_size (all four occurrences)
   J.3.13: no change

That leaves the matter of dealing with this for C++, Objective C and also
Objective C++, but I'd very much prefer to deal with C first, as that
seems the most straightforward, as is fundamental to the others.
Stuart Brady

More information about the Gcc-patches mailing list