M
Martin
I am reviewing this function:
unsigned long function(unsigned long *first, unsigned long *last)
{
unsigned long diff;
if ( (*last) < (*first) /* rollover occured */
{
period = (0xFFFFFFFF - (*first)) + (*last) + 1;
}
else /* no rollover */
{
period = (*last) - (*first);
}
return period;
}
The statement
period = (0xFFFFFFFF - (*first)) + (*last) + 1;
assumes a long is 32 bits wide. I noticed in K&R2 they talked about a
portable way of defining a constant - without assuming a particular width. I
came up with these:
Suggestion 1:
period = (~0UL - (*first)) + (*last) + 1;
Suggestion 2:
period = (ULONG_MAX - (*first)) + (*last) + 1;
The point of Suggestion 1 is that it sets all bits in an unsigned long,
irrespective of the width it happens to be. Suggestion 2 uses the symbolic
constant ULONG_MAX (the maximum value for an object of type unsigned long
int).
My questions are these:
(i) Am I right to try and make this non-width specific?
(ii) Do my suggestions so do?
Finally, as an adjunct, if I wanted to set a value, say 0xFFD1 in an
unsigned int that happens to be 16 bits wide at the moment, would I be
better off doing something like this:
ui = ~0x2EU;
so later when it's 24 or 32 bits, or whatever, all bits except 1, 2, 3, and
5 are still set?
unsigned long function(unsigned long *first, unsigned long *last)
{
unsigned long diff;
if ( (*last) < (*first) /* rollover occured */
{
period = (0xFFFFFFFF - (*first)) + (*last) + 1;
}
else /* no rollover */
{
period = (*last) - (*first);
}
return period;
}
The statement
period = (0xFFFFFFFF - (*first)) + (*last) + 1;
assumes a long is 32 bits wide. I noticed in K&R2 they talked about a
portable way of defining a constant - without assuming a particular width. I
came up with these:
Suggestion 1:
period = (~0UL - (*first)) + (*last) + 1;
Suggestion 2:
period = (ULONG_MAX - (*first)) + (*last) + 1;
The point of Suggestion 1 is that it sets all bits in an unsigned long,
irrespective of the width it happens to be. Suggestion 2 uses the symbolic
constant ULONG_MAX (the maximum value for an object of type unsigned long
int).
My questions are these:
(i) Am I right to try and make this non-width specific?
(ii) Do my suggestions so do?
Finally, as an adjunct, if I wanted to set a value, say 0xFFD1 in an
unsigned int that happens to be 16 bits wide at the moment, would I be
better off doing something like this:
ui = ~0x2EU;
so later when it's 24 or 32 bits, or whatever, all bits except 1, 2, 3, and
5 are still set?