From patchwork Mon Feb 4 14:34:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 31299 Received: (qmail 31306 invoked by alias); 4 Feb 2019 14:34:13 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 31289 invoked by uid 89); 4 Feb 2019 14:34:13 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.1 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, KAM_LAZY_DOMAIN_SECURITY, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=acceptable, retain, HTo:D*jp X-HELO: mx1.redhat.com From: Florian Weimer To: TAMUKI Shoichi Cc: libc-alpha@sourceware.org Subject: Re: Using array_length macro outside function References: <201902040553.AA04223@tamuki.linet.gr.jp> Date: Mon, 04 Feb 2019 15:34:09 +0100 In-Reply-To: <201902040553.AA04223@tamuki.linet.gr.jp> (TAMUKI Shoichi's message of "Mon, 04 Feb 2019 14:53:24 +0900") Message-ID: <87a7jbpqqm.fsf@oldenburg2.str.redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux) MIME-Version: 1.0 * TAMUKI Shoichi: > [1] to calculate the number of elements in the array. > > [1] https://sourceware.org/ml/libc-alpha/2017-10/msg01054.html > > Now, I tried to further improve this as patched below; > > ---------------------------------------------------------------------- > diff --git a/time/tst-strftime2.c b/time/tst-strftime2.c > index 57d2144..6c2d359 100644 > --- a/time/tst-strftime2.c > +++ b/time/tst-strftime2.c > @@ -25,8 +25,10 @@ > #include > > static const char *locales[] = { "ja_JP.UTF-8", "lo_LA.UTF-8", "th_TH.UTF-8" }; > +#define nlocales array_length (locales) > +static char ref[nlocales][nformats][ndates][100]; The other problem is that array_length (locales) is not a constant expression because a statement expression is never a constant expression. I had not considered these problems when I wrote the array_length macro. I would like to retain the verification that the macro argument is not a pointer. What do you think about the patch below? Thanks, Florian array_length: Make usable as a constant expression Do not use a statement expression and _Static_assert in array_length, so that array_length can be used at file scope and as a constant expression. The compiler error message looks like this, so this is still acceptable: t.c:3:28: error: zero width for bit-field ‘ARGUMENT_NOT_AN_ARRAY’ 0 * sizeof (struct { int ARGUMENT_NOT_AN_ARRAY: \ ^~~~~~~~~~~~~~~~~~~~~ t.c:10:7: note: in expansion of macro ‘array_length’ int b[array_length (c) + 1]; ^~~~~~~~~~~~ 2019-02-04 Florian Weimer * include/array_length.h (array_length): Do not use a statement expression and _Static_assert, so that array_length can be used at file scope and as a constant expression. diff --git a/include/array_length.h b/include/array_length.h index 65f583063d..cee8897ba7 100644 --- a/include/array_length.h +++ b/include/array_length.h @@ -21,13 +21,11 @@ /* array_length (VAR) is the number of elements in the array VAR. VAR must evaluate to an array, not a pointer. */ -#define array_length(var) \ - __extension__ ({ \ - _Static_assert (!__builtin_types_compatible_p \ - (__typeof (var), __typeof (&(var)[0])), \ - "argument must be an array"); \ - sizeof (var) / sizeof ((var)[0]); \ - }) +#define array_length(var) \ + (sizeof (var) / sizeof ((var)[0]) \ + + 0 * sizeof (struct { int ARGUMENT_NOT_AN_ARRAY: \ + 1 - (__builtin_types_compatible_p \ + (__typeof (var), __typeof (&(var)[0]))); })) /* array_end (VAR) is a pointer one past the end of the array VAR. VAR must evaluate to an array, not a pointer. */