-
Notifications
You must be signed in to change notification settings - Fork 455
[CDRIVER-6043] Modify definitions in intutil
to avoid compound-literals
#2056
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[CDRIVER-6043] Modify definitions in intutil
to avoid compound-literals
#2056
Conversation
The followin changes are made: - We avoid compound literals expanded from macros. This is to avoid buggy compound-literal support in VS 2017 (See CDRIVER-6043). Instead, we pass the relevant argument to a function that initializes the new aggregate object. This has the downside that we cannot use the macros in constant expressions, but that was a minor feature that wasn't really used anywhere. - Add a new macro to define bit masks. This simplifies the expressions that build bit patterns used for two's complement arithmetic. - Rename the members of `mlib_upsized_integer` to give them meaningful names.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very welcome changes! Minor suggestions mostly concerning type/signedness consistency, but otherwise LGTM.
src/common/src/mlib/intutil.h
Outdated
/** | ||
* @brief Like `sizeof`, but returns the number of bits in the object representation | ||
*/ | ||
#define mlib_bitsizeof(T) ((sizeof (T)) * CHAR_BIT) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#define mlib_bitsizeof(T) ((sizeof (T)) * CHAR_BIT) | |
#define mlib_bitsizeof(T) ((sizeof (T)) * ((size_t) CHAR_BIT)) |
Type consistency.
src/common/src/mlib/intutil.h
Outdated
/** | ||
* @brief Generate a mask of contiguous bits. | ||
* | ||
* @param NumOnes The number of contiguous 1 bits |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* @param NumOnes The number of contiguous 1 bits | |
* @param NumOnes The positive number of contiguous 1 bits |
To document the requirement that NumOnes > 0
:
// warning: shift count >= width of type [-Wshift-count-overflow]
// runtime error: shift exponent 64 is too large for 64-bit type 'unsigned long'
mlib_bits(0, 0)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tweaked the definition to support setting zero 1
bits to "do the right thing", also tests for this.
src/common/src/mlib/intutil.h
Outdated
* @brief Generate a mask of contiguous bits. | ||
* | ||
* @param NumOnes The number of contiguous 1 bits | ||
* @param NumZeros The number of contiguous 0 bits to set in the low position |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* @param NumZeros The number of contiguous 0 bits to set in the low position | |
* @param NumZeros The non-negative number of contiguous 0 bits to set in the low position |
To document the requirement that NumZeroes >= 0
.
src/common/src/mlib/intutil.h
Outdated
#define mlib_bits(NumOnes, NumZeros) ( \ | ||
/* Create a set of N 1 bits */ \ | ||
(/* Create a mask of all 0b1111... */ \ | ||
~UINTMAX_C(0) \ | ||
/* Shift down the chop off to only the number of 1 bits we want */ \ | ||
>> (mlib_bitsizeof(uintmax_t) - (uintmax_t)(NumOnes))) \ | ||
/* Shift left to add the low zeros */\ | ||
<< ((uintmax_t)(NumZeros)) \ | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#define mlib_bits(NumOnes, NumZeros) ( \ | |
/* Create a set of N 1 bits */ \ | |
(/* Create a mask of all 0b1111... */ \ | |
~UINTMAX_C(0) \ | |
/* Shift down the chop off to only the number of 1 bits we want */ \ | |
>> (mlib_bitsizeof(uintmax_t) - (uintmax_t)(NumOnes))) \ | |
/* Shift left to add the low zeros */\ | |
<< ((uintmax_t)(NumZeros)) \ | |
) | |
#define mlib_bits(NumOnes, NumZeros) ( \ | |
(~UINTMAX_C(0) >> (mlib_bitsizeof(uintmax_t) - (uintmax_t)(NumOnes))) \ | |
<< ((uintmax_t)(NumZeros))) |
I think the thorough inline comments may be hurting readability more than helping. Suggest deferring the explanation to the doc comment above, which imo is sufficient.
src/common/src/mlib/intutil.h
Outdated
? ((T) mlib_bits(mlib_bitsizeof(T) - 1, 0)) \ | ||
: ((T) mlib_bits(mlib_bitsizeof(T), 0)))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
? ((T) mlib_bits(mlib_bitsizeof(T) - 1, 0)) \ | |
: ((T) mlib_bits(mlib_bitsizeof(T), 0)))) | |
? ((T) mlib_bits(mlib_bitsizeof(T) - 1u, 0)) \ | |
: ((T) mlib_bits(mlib_bitsizeof(T), 0)))) |
Signedness consistency.
src/common/src/mlib/ckdint.h
Outdated
@@ -460,7 +458,7 @@ static inline bool (mlib_mul) (uintmax_t *dst, bool dst_signed, bool a_signed, u | |||
mlib_noexcept | |||
{ | |||
// Multiplication is a lot more subtle | |||
const uintmax_t signbit = (UINTMAX_C (1) << ((sizeof (intmax_t) * CHAR_BIT) - 1)); | |||
const uintmax_t signbit = mlib_bits (1, mlib_bitsizeof (uintmax_t) - 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const uintmax_t signbit = mlib_bits (1, mlib_bitsizeof (uintmax_t) - 1); | |
const uintmax_t signbit = mlib_bits (1, mlib_bitsizeof (uintmax_t) - 1u); |
src/common/src/mlib/ckdint.h
Outdated
@@ -359,7 +357,7 @@ static inline bool (mlib_sub) (uintmax_t *dst, bool dst_signed, bool a_signed, u | |||
{ | |||
// Perform the subtraction using regular wrapping arithmetic | |||
const uintmax_t diff = *dst = a - b; | |||
const uintmax_t signbit = (UINTMAX_C (1) << ((sizeof (intmax_t) * CHAR_BIT) - 1)); | |||
const uintmax_t signbit = mlib_bits (1, mlib_bitsizeof (uintmax_t) - 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const uintmax_t signbit = mlib_bits (1, mlib_bitsizeof (uintmax_t) - 1); | |
const uintmax_t signbit = mlib_bits (1, mlib_bitsizeof (uintmax_t) - 1u); |
src/common/src/mlib/ckdint.h
Outdated
@@ -265,7 +263,7 @@ static inline bool (mlib_add) (uintmax_t *dst, bool dst_signed, bool a_signed, u | |||
// Perform regular wrapping arithmetic on the unsigned value. The bit pattern | |||
// is equivalent if there is two's complement signed arithmetic. | |||
const uintmax_t sum = *dst = a + b; | |||
const uintmax_t signbit = (UINTMAX_C (1) << ((sizeof (intmax_t) * CHAR_BIT) - 1)); | |||
const uintmax_t signbit = mlib_bits (1, mlib_bitsizeof (uintmax_t) - 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const uintmax_t signbit = mlib_bits (1, mlib_bitsizeof (uintmax_t) - 1); | |
const uintmax_t signbit = mlib_bits (1, mlib_bitsizeof (uintmax_t) - 1u); |
src/common/src/mlib/ckdint.h
Outdated
#define _mlibMinofSigned(V) ((0 & (V)) - (UINTMAX_C (1) << ((sizeof (V) * CHAR_BIT) - 1))) | ||
#define _mlibMinofSigned(V) \ | ||
/* NOLINTNEXTLINE(bugprone-sizeof-expression) */ \ | ||
(0 - mlib_bits(1, mlib_bitsizeof(V) - 1)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(0 - mlib_bits(1, mlib_bitsizeof(V) - 1)) | |
(0 - mlib_bits(1, mlib_bitsizeof(V) - 1u)) |
src/common/src/mlib/ckdint.h
Outdated
#define _mlibMaxofSigned(V) (_mlibMaxofUnsigned (V) >> 1ull) | ||
#define _mlibMaxofSigned(V) \ | ||
/* NOLINTNEXTLINE(bugprone-sizeof-expression) */ \ | ||
mlib_bits(mlib_bitsizeof(V) - 1, 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mlib_bits(mlib_bitsizeof(V) - 1, 0) | |
mlib_bits(mlib_bitsizeof(V) - 1u, 0) |
The following changes are made:
We avoid compound literals expanded from macros. This is to avoid buggy compound-literal support in VS 2017 (See CDRIVER-6043).
Instead, we pass the relevant argument to a function that initializes the new aggregate object.
This has the downside that we cannot use the macros in constant expressions, but that was a minor feature that wasn't really used anywhere.
Add a new macro to define bit masks. This simplifies the expressions that build bit patterns used for two's complement arithmetic.
Rename the members of
mlib_upsized_integer
to give them meaningful names.This doesn't fully fix CDRIVER-6043, but will avoid future subtle issues with VS 2017.