[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
proposal: lib/verify.h
From: |
Jim Meyering |
Subject: |
proposal: lib/verify.h |
Date: |
Wed, 29 Jun 2005 22:24:07 +0200 |
[to make a long story short, skip down to the `I propose...'
part near the end. ]
Yesterday I did this in coreutils
* src/pr.c (main, store_char): Use x2realloc on 1-byte base types,
not x2nrealloc. The former is a little more concise and readable.
N.B. this sort of transformation is ok only when the base type is
unlikely ever to change to a multibyte type.
* src/du.c (show_date): Likewise.
* src/date.c (show_date): Likewise.
* src/od.c (dump_strings): Likewise.
* src/sort.c (fillbuf): Likewise.
For example:
diff -p -u0 -r1.315 -r1.316 sort.c
--- sort.c 16 Jun 2005 21:33:43 -0000 1.315
+++ sort.c 28 Jun 2005 16:33:20 -0000 1.316
@@ -1062 +1062 @@ fillbuf (struct buffer *buf, FILE *fp, c
- buf->buf = x2nrealloc (buf->buf, &buf->alloc, sizeof *(buf->buf));
+ buf->buf = x2realloc (buf->buf, &buf->alloc);
But then I realized that while the above changes made things a
little more concise and maybe even a little cleaner, they also
added a potential risk.
So I added an intermediate X2REALLOC macro, and made all of the
above use that instead of using x2realloc directly.
2005-06-29 Jim Meyering <address@hidden>
* xalloc.h (VERIFY_EXPR): Define.
(X2REALLOC): New macro, to make using x2realloc a little safer.
Index: lib/xalloc.h
===================================================================
RCS file: /fetish/cu/lib/xalloc.h,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -p -u -r1.27 -r1.28
--- lib/xalloc.h 14 May 2005 07:58:07 -0000 1.27
+++ lib/xalloc.h 29 Jun 2005 16:33:17 -0000 1.28
@@ -56,6 +56,15 @@ void *x2nrealloc (void *p, size_t *pn, s
void *xmemdup (void const *p, size_t s);
char *xstrdup (char const *str);
+# define VERIFY_EXPR(assertion) \
+ (void)((struct {char a[(assertion) ? 1 : -1]; } *) 0)
+
+/* Using x2realloc (when appropriate) usually makes your code more
+ readable than using x2nrealloc, but it also makes it so your
+ code will malfunction if sizeof (*P) ever becomes 2 or greater.
+ So use this macro instead of using x2realloc directly. */
+# define X2REALLOC(P, PN) (VERIFY_EXPR (sizeof(*P) == 1), x2realloc (P, PN))
+
/* Return 1 if an array of N objects, each of size S, cannot exist due
to size arithmetic overflow. S must be positive and N must be
nonnegative. This is a macro, not an inline function, so that it
Before, this definition of VERIFY_EXPR was only in coreutils/src/system.h.
Now, a copy is in coreutils/lib/xalloc.h, too. I like to avoid duplication.
Then there is a companion macro in coreutils/src/system.h, VERIFY:
(updated a couple of hours ago)
#define GL_CONCAT...
#define VERIFY(assertion) \
struct GL_CONCAT (compile_time_assert_, __LINE__) \
{ char a[(assertion) ? 1 : -1]; }
that is similar to the `verify' macro used in these gnulib files:
exclude.c
mktime.c
strtoimax.c
utimecmp.c
Plus, I want to use it in argmatch:
Index: lib/argmatch.h
===================================================================
RCS file: /fetish/cu/lib/argmatch.h,v
retrieving revision 1.24
diff -u -p -u -0 -r1.24 argmatch.h
--- lib/argmatch.h 14 May 2005 07:58:06 -0000 1.24
+++ lib/argmatch.h 29 Jun 2005 16:52:19 -0000
@@ -38,5 +38,2 @@
-# define ARGMATCH_VERIFY(Arglist, Vallist) \
- struct argmatch_verify \
- { \
- char argmatch_verify[ARGMATCH_CONSTRAINT(Arglist, Vallist) ? 1 : -1]; \
- }
+# define ARGMATCH_VERIFY(Arglist, Vallist) \
+ VERIFY (ARGMATCH_CONSTRAINT (Arglist, Vallist))
so that I can use ARGMATCH_VERIFY twice in cp.c's
global scope (currently I cannot) and 6 times in ls.c's
BTW, these new uses of ARGMATCH_VERIFY exposed two
arrays that were too long by a single `0' entry.
But both were harmless.
================================
I propose to add a new file, verify.h, and to include
in it these definitions:
#define GL_CONCAT0(x, y) x##y
#define GL_CONCAT(x, y) GL_CONCAT0 (x, y)
/* Verify a requirement at compile-time (unlike assert, which is runtime). */
#define VERIFY(assertion) \
struct GL_CONCAT (compile_time_assert_, __LINE__) \
{ char a[(assertion) ? 1 : -1]; }
/* Like the above, but use an expression rather than a struct declaration.
This macro may be used in some contexts where the other may not. */
#define VERIFY_EXPR(assertion) \
(void)((struct {char a[(assertion) ? 1 : -1]; } *) 0)
Then, the following files (with the possible exception of mktime.c
due to its glibc ties) would include "verify.h":
exclude.c
mktime.c
strtoimax.c
utimecmp.c
It'd be nice to make xalloc.h and argmatch.h include it, too, but
duplicating one primary definition in each is probably better than
adding the dependency -- at least for xalloc.h.
Opinions welcome.
- proposal: lib/verify.h,
Jim Meyering <=