This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [ping2][PATCH v2][BZ #12515] Improve precision of clock function


On 06/11/13 06:54, Siddhesh Poyarekar wrote:

> I think we could defer all discussion about overflow handling
> till we actually get to fixing it.

Yes, that's fine, thanks.

> Shouldn't this matter only when we're actually doing an overflow
> check?

Yes and no.  My guess is that you're right for this particular
case, even though GCC doesn't guarantee wraparound.

However, as GCC optimization gets more aggressive in this area, we
should use '#pragma GCC optimize ("wrapv")' in modules that assume
wraparound semantics on signed overflow, not only to fix problems
in the generated code (which may or may not exist -- who knows?),
but also to warn programmers about wraparound assumptions in the
affected modules.

Currently glibc uses -fwrapv only for time/mktime.c and for
time/zdump.c, but I expect it should also use -fwrapv for
sysdeps/unix/sysv/linux/clock.c too, and most likely there are
some other functions.


On 06/11/13 08:11, Rich Felker wrote:

> Having to be aware of an obscure GCC feature, which many
> readers would have to look up in the manual to understand, is a lot
> less understandable than unsigned arithmetic

I've tried it both ways, and found wrapv to be simpler.  It's
trivial to explain and to understand, whereas unsigned arithmetic
can be verbose and error-prone.  For example, here's how to check
for overflow when adding two integer time_t values A and B,
assuming wrapv:

    time_t sum = a + b;
    bool overflow = (sum < a) == (b < 0);

and here's how to do it with unsigned values, assuming
wrapv only when converting unsigned to signed:

    static time_t
    time_t_wrapv_add (time_t a, time_t b)
    {
      if (sizeof (time_t) <= sizeof (unsigned long int))
	return (unsigned long int) a + (unsigned long int) b;
      else
	return (unsigned long long int) a + (unsigned long int) b;
    }
    ...
    time_t sum = time_t_wrapv_add (a, b);
    bool overflow = (sum < a) == (b < 0);

The former is easier to read.  The latter is easier to get wrong
(I put in a sneaky typo to illustrate this), clutters up the
mainline code, and makes assumptions about time_t that are just
as obscure as wrapv.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]