From patchwork Mon Feb 4 05:53:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: TAMUKI Shoichi X-Patchwork-Id: 31290 Received: (qmail 127190 invoked by alias); 4 Feb 2019 05:54:41 -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 127178 invoked by uid 89); 4 Feb 2019 05:54:40 -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, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 spammy=keeping, evaluate, validation, locales X-HELO: mail.linet.jp Message-Id: <201902040553.AA04223@tamuki.linet.gr.jp> From: TAMUKI Shoichi Date: Mon, 04 Feb 2019 14:53:24 +0900 To: libc-alpha@sourceware.org Subject: Using array_length macro outside function MIME-Version: 1.0 Hello, As for time/tst-strftime2.c, I implemented using array_length macro [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; ---------------------------------------------------------------------- ---------------------------------------------------------------------- Can we remove the type validation from the current array_length macro? Or is there any way to use array_length macro outside function keeping the type validation? It seems that elf/dl-load.c has the same situation: ---------------------------------------------------------------------- static const size_t system_dirs_len[] = { SYSTEM_DIRS_LEN }; #define nsystem_dirs_len array_length (system_dirs_len) ---------------------------------------------------------------------- Thoughts? Regards, TAMUKI Shoichi 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 const char *formats[] = { "%EY", "%_EY", "%-EY" }; +#define nformats array_length (formats) static const struct { @@ -40,8 +42,9 @@ static const struct { 1, 3, 97 }, { 1, 3, 98 } }; +#define ndates array_length (dates) -static char ref[3][3][6][100]; +static char ref[nlocales][nformats][ndates][100]; static void mkreftable (void) @@ -51,9 +54,9 @@ mkreftable (void) static const int yrj[] = { 63, 64, 1, 2, 9, 10 }; static const int yrb[] = { 2531, 2532, 2532, 2533, 2540, 2541 }; - for (i = 0; i < array_length (locales); i++) - for (j = 0; j < array_length (formats); j++) - for (k = 0; k < array_length (dates); k++) + for (i = 0; i < nlocales; i++) + for (j = 0; j < nformats; j++) + for (k = 0; k < ndates; k++) { if (i == 0) { @@ -93,7 +96,7 @@ do_test (void) size_t r, e; mkreftable (); - for (i = 0; i < array_length (locales); i++) + for (i = 0; i < nlocales; i++) { if (setlocale (LC_ALL, locales[i]) == NULL) { @@ -101,9 +104,9 @@ do_test (void) continue; } printf ("[%s]\n", locales[i]); - for (j = 0; j < array_length (formats); j++) + for (j = 0; j < nformats; j++) { - for (k = 0; k < array_length (dates); k++) + for (k = 0; k < ndates; k++) { ttm.tm_mday = dates[k].d; ttm.tm_mon = dates[k].m; ---------------------------------------------------------------------- and it resulted in an error and the compilation failed: ---------------------------------------------------------------------- gcc tst-strftime2.c -c -std=gnu11 -fgnu89-inline -O2 -g -m64 -fmessage-length=0 -D_FORTIFY_SOURCE=2 -funwind-tables \ -fasynchronous-unwind-tables -U_FORTIFY_SOURCE -g -Wall -Wwrite-strings -Wundef -Werror -fmerge-all-constants -frounding-math \ -fstack-protector -Wstrict-prototypes -Wold-style-definition -fmath-errno -I../include \ -I/home/tamuki/rpmbuild/BUILD/glibc-2.29/cc-base/time -I/home/tamuki/rpmbuild/BUILD/glibc-2.29/cc-base \ -I../sysdeps/unix/sysv/linux/x86_64/64 -I../sysdeps/unix/sysv/linux/x86_64 -I../sysdeps/unix/sysv/linux/x86/include \ -I../sysdeps/unix/sysv/linux/x86 -I../sysdeps/x86/nptl -I../sysdeps/unix/sysv/linux/wordsize-64 -I../sysdeps/x86_64/nptl \ -I../sysdeps/unix/sysv/linux/include -I../sysdeps/unix/sysv/linux -I../sysdeps/nptl -I../sysdeps/pthread -I../sysdeps/gnu \ -I../sysdeps/unix/inet -I../sysdeps/unix/sysv -I../sysdeps/unix/x86_64 -I../sysdeps/unix -I../sysdeps/posix \ -I../sysdeps/x86_64/64 -I../sysdeps/x86_64/fpu/multiarch -I../sysdeps/x86_64/fpu -I../sysdeps/x86/fpu/include \ -I../sysdeps/x86/fpu -I../sysdeps/x86_64/multiarch -I../sysdeps/x86_64 -I../sysdeps/x86 -I../sysdeps/ieee754/float128 \ -I../sysdeps/ieee754/ldbl-96/include -I../sysdeps/ieee754/ldbl-96 -I../sysdeps/ieee754/dbl-64/wordsize-64 \ -I../sysdeps/ieee754/dbl-64 -I../sysdeps/ieee754/flt-32 -I../sysdeps/wordsize-64 -I../sysdeps/ieee754 \ -I../sysdeps/generic -I.. -I../libio -I. -D_LIBC_REENTRANT \ -include /home/tamuki/rpmbuild/BUILD/glibc-2.29/cc-base/libc-modules.h -DMODULE_NAME=testsuite \ -include ../include/libc-symbols.h -DPIC -DTOP_NAMESPACE=glibc \ -o /home/tamuki/rpmbuild/BUILD/glibc-2.29/cc-base/time/tst-strftime2.o -MD -MP -MF \ /home/tamuki/rpmbuild/BUILD/glibc-2.29/cc-base/time/tst-strftime2.o.dt -MT \ /home/tamuki/rpmbuild/BUILD/glibc-2.29/cc-base/time/tst-strftime2.o In file included from tst-strftime2.c:21:0: ../include/array_length.h:25:17: error: braced-group within expression allowed only inside a function __extension__ ({ \ ^ tst-strftime2.c:28:18: note: in expansion of macro 'array_length' #define nlocales array_length (locales) ^~~~~~~~~~~~ tst-strftime2.c:47:17: note: in expansion of macro 'nlocales' static char ref[nlocales][nformats][ndates][100]; ^~~~~~~~ ../include/array_length.h:25:17: error: braced-group within expression allowed only inside a function __extension__ ({ \ ^ tst-strftime2.c:31:18: note: in expansion of macro 'array_length' #define nformats array_length (formats) ^~~~~~~~~~~~ tst-strftime2.c:47:27: note: in expansion of macro 'nformats' static char ref[nlocales][nformats][ndates][100]; ^~~~~~~~ ../include/array_length.h:25:17: error: braced-group within expression allowed only inside a function __extension__ ({ \ ^ tst-strftime2.c:45:16: note: in expansion of macro 'array_length' #define ndates array_length (dates) ^~~~~~~~~~~~ tst-strftime2.c:47:37: note: in expansion of macro 'ndates' static char ref[nlocales][nformats][ndates][100]; ^~~~~~ tst-strftime2.c:47:13: error: 'ref' defined but not used [-Werror=unused-variable] static char ref[nlocales][nformats][ndates][100]; ^~~ cc1: all warnings being treated as errors make[2]: *** [../o-iterator.mk:9: /home/tamuki/rpmbuild/BUILD/glibc-2.29/cc-base/time/tst-strftime2.o] Error 1 ---------------------------------------------------------------------- Can we use array_length macro outside function? If the type validation is removed from the current array_length macro as patched below, it can be compiled successfully. ---------------------------------------------------------------------- diff --git a/include/array_length.h b/include/array_length.h index 65f5830..c9ce702 100644 --- a/include/array_length.h +++ b/include/array_length.h @@ -21,13 +21,7 @@ /* 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])) /* array_end (VAR) is a pointer one past the end of the array VAR. VAR must evaluate to an array, not a pointer. */