[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Bug-gnulib] Re: gnulib/lib exclude.c,1.18,1.19
From: |
Paul Eggert |
Subject: |
Re: [Bug-gnulib] Re: gnulib/lib exclude.c,1.18,1.19 |
Date: |
16 Oct 2003 11:31:34 -0700 |
User-agent: |
Gnus/5.09 (Gnus v5.9.0) Emacs/21.3 |
Bruno Haible <address@hidden> writes:
> Usually I use
> N_ALLOC = 2 * N_ALLOC + 1;
> or
> N_ALLOC = 2 * N_ALLOC + 10;
Unfortunately neither of these solutions is robust if sizeof *(V) is
1, because the addition might overflow in that case. The existing
code avoids that problem.
Also, I'd rather fix this with a function than a macro. How about if
we should add something like this?
void xdrealloc (void **pointer, size_t *current_alloc,
size_t initial_alloc, size_t element_size);
This would set *current_alloc to be the maximum of 2 * *current_alloc
and initial_alloc, except that it would call xalloc_die if the result
would exceed SIZE_MAX / element_size. It would then call
*pointer = xrealloc (*pointer, *current_alloc * element_size);
That way, we could replace this:
ex->exclude = xnrealloc (ex->exclude, ex->exclude_alloc,
2 * sizeof *ex->exclude);
ex->exclude_alloc *= 2;
with this:
xdrealloc (&ex->exclude, &ex->exclude_alloc, sizeof *ex->ex_exclude, 10);
The 'd' in 'xdrealloc' is short for 'double the size of'.
This isn't quite a nice as the macro in that it repeats ex->exclude
once, but it does have functional semantics and that is an advantage.
PS. As a related point, it's common for code to do something like
this:
foo *table = NULL;
size_t table_size = 0;
...
[perhaps grow table as shown above]
...
foo *table_lim = table + table_size;
foo *p;
for (p = table; p < table_lim; p++)
bar (p);
This has undefined behavior if table == NULL, since you can't add 0 to
a null pointer in C. However, I don't know of any GNU target where
(foo *) NULL + 0 does not equal NULL. I think some gnulib code
already assumes that (foo *) NULL + 0 is NULL, so I'll add a comment
to that effect in README.