public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Alejandro Colomar <colomar.6.4.3@gmail.com>
To: libc-alpha@sourceware.org
Cc: libc-coord@lists.openwall.com, libstdc++@gcc.gnu.org,
	gcc@gcc.gnu.org, linux-kernel@vger.kernel.org,
	linux-man@vger.kernel.org, fweimer@redhat.com,
	jwakely@redhat.com, ville.voutilainen@gmail.com, enh@google.com,
	rusty@rustcorp.com.au
Subject: Re: [PATCH v2] <sys/param.h>: Add nitems() and snitems() macros
Date: Fri, 25 Sep 2020 16:10:02 +0200	[thread overview]
Message-ID: <f6257d7d-1cea-b45c-a858-b80bbc1f18b1@gmail.com> (raw)
In-Reply-To: <20200925132000.235033-1-colomar.6.4.3@gmail.com>



On 2020-09-25 15:20, Alejandro Colomar wrote:
 > 'nitems()' calculates the length of an array in number of items.
 > It is safe: if a pointer is passed to the macro (or function, in C++),
 > the compilation is broken due to:
 >   - In >= C11: _Static_assert()
 >   - In C89, C99: Negative anonymous bitfield
 >   - In C++: The template requires an array
 >
 > 'snitems()' is equivalent to nitems(),
 > but it returns a 'ptrdiff_t' instead of a 'size_t'.
 > It is useful for comparison with signed integer values.
 >
 > Some BSDs already provide a macro nitems() in <sys/param.h>,
 > although it usually doesn't provide safety against pointers.
 >
 > This patch uses the same name for compatibility reasons,
 > and to be the least disruptive with existing code.
 >
 > This patch also adds some other macros, which are required by 'nitems()':
 >
 > __is_same_type(_A, _B):
 > Returns non-zero if the two input arguments are of the same type.
 >
 > __is_array(_Arr):
 > Returns non-zero if the input argument is of an array type.
 >
 > __must_be(_Expr, _Msg):
 > Allows using _Static_assert() everywhere an expression can be used.
 > It evaluates '(int)0' or breaks the compilation.
 >
 > __must_be_array(_Arr):
 > It evaluates to '(int)0' if the argument is of an array type.
 > Else, it breaks compilation.
 >
 > __array_len(_Arr):
 > It implements the basic sizeof division needed to calculate the array 
length.
 >
 >
 > P.S.: I'd like to put this patch in the public domain.
 >
 >
 > Signed-off-by: Alejandro Colomar <colomar.6.4.3@gmail.com>
 > ---

I patched my own system's <sys/param.h> with this,
and while 'nitems()' works fine,
I had to include <stddef.h> in my main.c to be able to use 'snitems()',
because I didn't have 'ptrdiff_t',
eventhough <sys/param.h> already includes <stddef.h>.

I completely ignore the mechanisms behind system headers including
other system headers.

Moreover, I didn't find 'ptrdiff_t' defined in any of my systems headers
I used 'user@debian:/usr/include$ grep -rn ptrdiff_t'.  Does GCC do magic?

What's the problem with that?  How should I fix the patch?

My system:  Debian bullseye/sid; x86-64; gcc 10; libc 2.31-3

Thanks,

Alex


 >   misc/sys/param.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++++
 >   1 file changed, 60 insertions(+)
 >
 > diff --git a/misc/sys/param.h b/misc/sys/param.h
 > index d7c319b157..88e95c2dba 100644
 > --- a/misc/sys/param.h
 > +++ b/misc/sys/param.h
 > @@ -102,5 +102,65 @@
 >   #define MIN(a,b) (((a)<(b))?(a):(b))
 >   #define MAX(a,b) (((a)>(b))?(a):(b))
 >
 > +/* Macros related to the types of variables */
 > +# define __is_same_type(_A, _B) 
__builtin_types_compatible_p(__typeof__(_A), \
 > + 
__typeof__(_B))
 > +# define __is_array(_Arr)	(!__is_same_type((_Arr), &(_Arr)[0]))
 > +
 > +/* Macros for embedding _Static_assert() in expressions */
 > +# if __STDC_VERSION__ >= 201112L
 > +#  define __must_be(_Expr, _Msg)  ( 
          \
 > +        0 * (int)sizeof( 
          \
 > +          struct { 
          \
 > +            _Static_assert((_Expr), _Msg); 
          \
 > +            char _ISO_C_forbids_a_struct_with_no_members; 
          \
 > +          } 
          \
 > +        ) 
          \
 > +)
 > +# else
 > +#  define __must_be(_Expr, _Msg)  ( 
          \
 > +        0 * (int)sizeof( 
          \
 > +          struct { 
          \
 > +            int  : (-!(_Expr)); 
          \
 > +            char _ISO_C_forbids_a_struct_with_no_members; 
          \
 > +          } 
          \
 > +        ) 
          \
 > +)
 > +# endif
 > +
 > +# define __must_be_array(_Arr)	__must_be(__is_array(_Arr), "Must be 
an array!")
 > +
 > +/* Macros for array sizes */
 > +#if defined(__cplusplus)
 > +# if __cplusplus >= 201103L
 > +template<typename _Tp, std::size_t _Len>
 > +  constexpr inline std::size_t
 > +  nitems(const _Tp(&)[_Len]) __THROW
 > +  {
 > +    return _Len;
 > +  }
 > +
 > +template<typename _Tp, std::size_t _Len>
 > +  constexpr inline std::ptrdiff_t
 > +  snitems(const _Tp(&)[_Len]) __THROW
 > +  {
 > +    return _Len;
 > +  }
 > +
 > +# else /* __cplusplus < 201103L */
 > +template<typename _Tp, std::size_t _Len>
 > +  char
 > +  (&__nitems_chararr(const _Tp(&)[_Len]))[_Len];
 > +
 > +#  define nitems(_Arr)          (sizeof(__nitems_chararr(_Arr)))
 > +#  define snitems(_Arr) 
(static_cast<std::ptrdiff_t>(nitems(_Arr)))
 > +# endif /* __cplusplus < 201103L */
 > +
 > +#else /* !defined(__cplusplus) */
 > +# define __array_len(_Arr)      (sizeof(_Arr) / sizeof((_Arr)[0]))
 > +# define nitems(_Arr)           (__array_len(_Arr) + 
__must_be_array(_Arr))
 > +# define snitems(_Arr)          ((ptrdiff_t)nitems(_Arr))
 > +#endif /* !defined(__cplusplus) */
 > +
 >
 >   #endif  /* sys/param.h */
 >

  reply	other threads:[~2020-09-25 14:10 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-20 23:00 Expose 'array_length()' macro in <sys/cdefs.h> or <sys/param.h> Alejandro Colomar
2020-09-21  8:38 ` Florian Weimer
2020-09-21 10:11   ` Alejandro Colomar
2020-09-21 10:33     ` Florian Weimer
2020-09-21 12:47       ` Alejandro Colomar
2020-09-21 15:47         ` [libc-coord] " enh
2020-09-22 16:25         ` Rich Felker
2020-09-22 16:44           ` Jonathan Wakely
2020-09-22 16:53             ` Ville Voutilainen
2020-09-21 14:01       ` Jonathan Wakely
2020-09-21 21:52         ` Expose 'array_length()' macro in <sys/param.h> Alejandro Colomar
2020-09-21 22:04           ` Jonathan Wakely
2020-09-21 22:13             ` Ville Voutilainen
2020-09-22  9:10               ` Alejandro Colomar
2020-09-22  9:40                 ` Jonathan Wakely
2020-09-22 10:01                   ` Florian Weimer
2020-09-22 10:35                     ` Alejandro Colomar
2020-09-22 11:40               ` Florian Weimer
2020-09-22 14:58                 ` [RFC] <sys/param.h>: Add nitems() and snitems() macros Alejandro Colomar
2020-09-25 13:20                   ` [PATCH v2] " Alejandro Colomar
2020-09-25 14:10                     ` Alejandro Colomar [this message]
2020-09-25 14:48                       ` Jonathan Wakely
2020-09-25 16:30                         ` Alejandro Colomar
2020-09-25 17:39                           ` Jonathan Wakely
2020-09-25 17:42                           ` Jonathan Wakely
2020-09-25 17:46                             ` Alejandro Colomar
2020-09-25 19:37                               ` [PATCH v3] <sys/param.h>: Add nitems() Alejandro Colomar
2020-09-22  9:16             ` [libc-coord] Re: Expose 'array_length()' macro in <sys/param.h> Florian Weimer
2020-09-30 15:58 ` Expose 'array_length()' macro in <sys/cdefs.h> or <sys/param.h> Joseph Myers
2020-09-30 20:39   ` Alejandro Colomar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=f6257d7d-1cea-b45c-a858-b80bbc1f18b1@gmail.com \
    --to=colomar.6.4.3@gmail.com \
    --cc=enh@google.com \
    --cc=fweimer@redhat.com \
    --cc=gcc@gcc.gnu.org \
    --cc=jwakely@redhat.com \
    --cc=libc-alpha@sourceware.org \
    --cc=libc-coord@lists.openwall.com \
    --cc=libstdc++@gcc.gnu.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-man@vger.kernel.org \
    --cc=rusty@rustcorp.com.au \
    --cc=ville.voutilainen@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).