From patchwork Tue Feb 5 12:29:08 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 31311 Received: (qmail 70467 invoked by alias); 5 Feb 2019 12:29:14 -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 70458 invoked by uid 89); 5 Feb 2019 12:29:14 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=H*Ad:D*jp X-HELO: mx1.redhat.com From: Florian Weimer To: Joseph Myers Cc: TAMUKI Shoichi , Subject: Re: Using array_length macro outside function References: <201902040553.AA04223@tamuki.linet.gr.jp> <87a7jbpqqm.fsf@oldenburg2.str.redhat.com> Date: Tue, 05 Feb 2019 13:29:08 +0100 In-Reply-To: (Joseph Myers's message of "Mon, 4 Feb 2019 23:33:56 +0000") Message-ID: <87va1ybeqz.fsf@oldenburg2.str.redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux) MIME-Version: 1.0 * Joseph Myers: > On Mon, 4 Feb 2019, Florian Weimer wrote: > >> 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: \ > > You can use _Static_assert inside a struct; you don't need to do things > with bit-field sizes. That's certainly nicer. Please consider the patch below. Thanks, Florian array_length: Make usable as a constant expression Do not use a statement expression in array_length, so that array_length can be used at file scope and as a constant expression. Instead, put the _Static_assert into a struct (as a declaration), and nest this in the expression using a sizeof expression. 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. Tested-by: TAMUKI Shoichi diff --git a/include/array_length.h b/include/array_length.h index 65f583063d..db98a69899 100644 --- a/include/array_length.h +++ b/include/array_length.h @@ -22,12 +22,12 @@ /* 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]); \ - }) + (sizeof (var) / sizeof ((var)[0]) \ + + 0 * sizeof (struct { \ + _Static_assert (!__builtin_types_compatible_p \ + (__typeof (var), __typeof (&(var)[0])), \ + "argument must be an array"); \ + })) /* array_end (VAR) is a pointer one past the end of the array VAR. VAR must evaluate to an array, not a pointer. */