[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Removing some workarounds for big integers
From: |
Philipp Stephani |
Subject: |
Re: Removing some workarounds for big integers |
Date: |
Sun, 9 Aug 2020 17:39:11 +0200 |
Am Mi., 5. Aug. 2020 um 08:11 Uhr schrieb Paul Eggert <eggert@cs.ucla.edu>:
>
> On 8/1/20 1:09 PM, Philipp Stephani wrote:
> > Am Mo., 22. Apr. 2019 um 20:45 Uhr schrieb Paul Eggert <eggert@cs.ucla.edu>:
> >>
> >> On 4/22/19 9:59 AM, Philipp Stephani wrote:
> >>>
> >>>> +#define INTEGER_TO_INT(num, type)
> >>>> \
> >>>> + (TYPE_SIGNED (type)
> >>>> \
> >>>> + ? ranged_integer_to_int ((num), TYPE_MINIMUM (type), TYPE_MAXIMUM
> >>>> (type)) \
> >>>> + : ranged_integer_to_uint ((num), TYPE_MINIMUM (type)))
> >>>> ^^^^^^^^^^^^
> >>>> This should be TYPE_MAXIMUM.
> >>>
> >>> Thanks, fixed
> >>>
> >> More important, INTEGER_TO_INT's type conversion messes up and can cause
> >> a signal on picky platforms.
> >
> > How so?
>
> The type conversion is messed up because on conventional platforms
> INTEGER_TO_INT returns a value of uintmax_t, which means that an expression
> like
> 'INTEGER_TO_INT (n, t) < 0' will always be false, even if N is negative and T
> is
> a signed type.
>
> The "picky platform" is one where conversion from unsigned to signed signals
> when the value is out of range for the signed type; this behavior is allowed
> by
> POSIX and the C standard and I imagine some debugging implementations might
> check for it. On these implementations,
Yeah, good point, I forgot about the annoying behavior of the ternary operator.
>
> To work around this problem, the macro could have another argument, being the
> lvalue destination; that would avoid these problems. However, it'd be more
> awkward to use. At some point it's easier to avoid the macro and use the
> underlying functions.
I wouldn't agree to that. The large advantage of packaging the
conversion up into a single macro is that the range check is always
correct and only needs to be coded once. Repeating the range check for
each caller is rather error-prone. So I think a void-returning macro
makes sense. It wouldn't even need another argument, as the type
follows from the destination. (At least if __typeof__ is available.)