svn commit: r270227 - head/sys/sys

Bruce Evans brde at optusnet.com.au
Tue Aug 26 13:58:49 UTC 2014


On Tue, 26 Aug 2014, Ed Schouten wrote:

> On 20 August 2014 18:32, Davide Italiano <davide at freebsd.org> wrote:
>> -       _bt->frac = _ts->tv_nsec * (uint64_t)18446744073LL;
>> +       _bt->frac = _ts->tv_nsec * (uint64_t)18446744073;
>
> You could also consider using UINT64_C(18446744073); that's the C
> standard way of creating an integer constant having a certain type.

That would be a further obfuscation.  The *INT<n>C() macros expand to
integer constant expressions of the specified type suitable for use
in #if preprocessing directives.  (It is otherwise difficult to
detemine the correct suffix, to add to the constant to give it the
specified type).  There are no preprocessing directives here, so a
simple cast works.  The cast could also be applied to the other
operand but it is easier to read when applied to the constant.

UINT64_C() might work around the compiler bug of warning for constants
larger than ULONG_MAX, depending on its implementation.  I think it
always does.  On 64-bit arches, the above constant is not larger than
ULONG_MAX so there is no problem, and on 32-bit arches the implementation
can't be much different from appending 'ULL'.

The expression could also be written without a cast and without using
UINT64_C(), by using a 'ULL' suffix instead of 'LL'.  That would still
use the long long abomination, and be different obfuscation -- the
type of the constant doesn't really matter, but we need to promote
to the type of 'frac', that is, uint64_t.  'ULL' works because long
longs are at least 64 bits (and I think unsigned long longs are also
2's complemention, so their type is larger than uint64_t.

Bruce


More information about the svn-src-all mailing list