Skip to content

Commit 57a36b7

Browse files
author
Erik McClure
committed
SIGNED_MIN now calculated without causing undefined behavior
1 parent cb72c5b commit 57a36b7

File tree

3 files changed

+10
-11
lines changed

3 files changed

+10
-11
lines changed

include/bss_alloc_ring.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,9 +212,12 @@ namespace bss_util {
212212
}
213213

214214
BSS_ALIGN(16) bss_PTag<Bucket> _gc; // Contains a list of discarded buckets
215+
#pragma warning(push)
216+
#pragma warning(disable:4251)
215217
BSS_ALIGN(16) std::atomic<Bucket*> _root;
216218
BSS_ALIGN(64) std::atomic<size_t> _readers; // How many threads are currently depending on _root to not change
217219
BSS_ALIGN(64) std::atomic_bool _flag; // Blocking flag for when _root needs to change
220+
#pragma warning(pop)
218221
size_t _lastsize; // Last size used for a bucket.
219222
Bucket* _list; // root of permanent list of all active allocated buckets.
220223
};

include/bss_util.h

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,11 @@ namespace bss_util {
7171
#endif
7272
typedef typename std::make_unsigned<SIGNED>::type UNSIGNED;
7373

74-
static const UNSIGNED UNSIGNED_MIN=0;
75-
static const UNSIGNED UNSIGNED_MAX=(((UNSIGNED)2)<<(BITS-1))-((UNSIGNED)1); //these are all done carefully to ensure no overflow is ever utilized unless appropriate and it respects an arbitrary bit limit. We use 2<<(BITS-1) here to avoid shifting more bits than there are bits in the type.
76-
static const SIGNED SIGNED_MIN_RAW=(((SIGNED)1)<<(BITS-1)); // When we have normal bit lengths (8,16, etc) this will correctly result in a negative value in two's complement.
77-
#ifdef BSS_COMPILER_GCC
78-
static const SIGNED SIGNED_MIN=-((__int128)SIGNED_MIN_RAW); // GCC is a pedantic fuckwad that treats signed overflow as undefined even if I want it to overflow, so we work around it.
79-
#else
80-
static const SIGNED SIGNED_MIN=(-SIGNED_MIN_RAW); // However if we have unusual bit lengths (3,19, etc) the raw bit representation will be technically correct in the context of that sized integer, but since we have to round to a real integer size to represent the number, the literal interpretation will be wrong. This yields the proper minimum value.
81-
#endif
82-
static const SIGNED SIGNED_MAX=((~SIGNED_MIN_RAW)&UNSIGNED_MAX);
74+
static const UNSIGNED UNSIGNED_MIN = 0;
75+
static const UNSIGNED UNSIGNED_MAX = (((UNSIGNED)2) << (BITS - 1)) - ((UNSIGNED)1); //these are all done carefully to ensure no overflow is ever utilized unless appropriate and it respects an arbitrary bit limit. We use 2<<(BITS-1) here to avoid shifting more bits than there are bits in the type.
76+
static const SIGNED SIGNED_MIN_RAW = (SIGNED)(((UNSIGNED)1) << (BITS - 1)); // When we have normal bit lengths (8,16, etc) this will correctly result in a negative value in two's complement.
77+
static const SIGNED SIGNED_MIN = (((SIGNED)~0) << (BITS - 1)); // However if we have unusual bit lengths (3,19, etc) the raw bit representation will be technically correct in the context of that sized integer, but since we have to round to a real integer size to represent the number, the literal interpretation will be wrong. This yields the proper minimum value.
78+
static const SIGNED SIGNED_MAX = ((~SIGNED_MIN_RAW)&UNSIGNED_MAX);
8379
};
8480
template<typename T>
8581
struct TBitLimit : public BitLimit<sizeof(T)<<3> {};

test/main.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4129,7 +4129,7 @@ void _locklessqueue_consume(void* p)
41294129
{
41304130
while(!startflag.load());
41314131
T* q = (T*)p;
4132-
uint c;
4132+
unsigned short c;
41334133
while((c = lq_pos.fetch_add(1, std::memory_order_relaxed))<TESTNUM) {
41344134
while(!q->Pop(lq_end[c]));
41354135
}
@@ -4140,7 +4140,7 @@ void _locklessqueue_produce(void* p)
41404140
{
41414141
while(!startflag.load());
41424142
T* q = (T*)p;
4143-
uint64 c;
4143+
size_t c;
41444144
while((c = lq_c.fetch_add(1, std::memory_order_relaxed))<=TESTNUM) {
41454145
q->Push(c);
41464146
}

0 commit comments

Comments
 (0)