|
Message-ID: <e734429a-d543-7e75-48e9-a8297a94b035@gmail.com> Date: Mon, 21 Sep 2020 23:52:13 +0200 From: Alejandro Colomar <colomar.6.4.3@...il.com> To: Jonathan Wakely <jwakely@...hat.com>, Florian Weimer <fweimer@...hat.com> Cc: gcc@....gnu.org, libstdc++@....gnu.org, Libc-alpha <libc-alpha@...rceware.org>, libc-coord@...ts.openwall.com Subject: Re: Expose 'array_length()' macro in <sys/param.h> I have developed this draft code, the C++ part being based on what you wrote. I am a C programmer, and my C++ is very basic, and I tend to write C-compatible code when I need C++, so I can't really write the C++ part. I tested the code with all C versions (--std= {c89, c99, c11, c18, c2x}), and it worked for all of them (correctly returning 18 in all of them), and if I uncomment the part of the pointer, it has a nice error message. I used `-Wall -Wextra -Werror -pedantic -Wno-vla -Wno-sizeof-pointer-div`. However, the C++ part needs some work to be able to compile. Would you mind finishing it? Thanks, Alex ------------------------------------------------------------------ #if defined(__cplusplus) # include <cstddef> # if __cplusplus >= 201703L # include <array> # define array_length(arr) (std:size(arr)) # else # if __cplusplus >= 201103L constexpr # endif inline std::size_t array_length(const T(&array)[N]) # if __cplusplus >= 201103L noexcept # endif { return N; } # endif # if __cplusplus >= 202002L # define array_slength(arr) (std:ssize(arr)) # else # if __cplusplus >= 201103L constexpr # endif inline std::ptrdiff_t array_slength(const T(&array)[N]) # if __cplusplus >= 201103L noexcept # endif { return N; } # endif #else /* !defined(__cplusplus) */ #include <stddef.h> # define __is_same_type(a, b) \ __builtin_types_compatible_p(__typeof__(a), __typeof__(b)) # define __is_array(arr) (!__is_same_type((arr), &(arr)[0])) # if __STDC_VERSION__ >= 201112L # define __must_be(e, msg) ( \ 0 * (int)sizeof( \ struct { \ _Static_assert((e), msg); \ char ISO_C_forbids_a_struct_with_no_members__; \ } \ ) \ ) # else # define __must_be(e, msg) ( \ 0 * (int)sizeof( \ struct { \ int : (-!(e)); \ char ISO_C_forbids_a_struct_with_no_members__; \ } \ ) \ ) # endif # define __must_be_array(arr) __must_be(__is_array(arr), "Must be an array!") # define __array_length(arr) (sizeof(arr) / sizeof((arr)[0])) # define array_length(arr) (__array_length(arr) + __must_be_array(arr)) # define array_slength(arr) ((ptrdiff_t)array_length(arr)) #endif int main(void) { int a[5]; const int x = 6; int b[x]; #if __cplusplus >= 201103L constexpr #endif int y = 7; int c[y]; int *p; (void)p; return array_slength(a) + array_slength(b) + array_length(c) /*+ array_length(p)*/; }
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.