From 2d163fa554136fe629c061144a5b22c5c293c9c0 Mon Sep 17 00:00:00 2001 From: Doyle Thai Date: Sun, 2 Jul 2017 14:47:38 +1000 Subject: [PATCH] Add fix for strict-aliasing in DqnRnd --- build.bat | 2 +- dqn.h | 16 +++++++++++++--- dqn_unit_test.cpp | 9 ++++----- makefile | 2 +- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/build.bat b/build.bat index 4b69675..fc3da94 100644 --- a/build.bat +++ b/build.bat @@ -31,7 +31,7 @@ REM Zi enables debug data, Z7 combines the debug files into one. REM W4 warning level 4 REM WX treat warnings as errors REM wd4201 ignore: nonstandard extension used: nameless struct/union -set CompileFlags=-EHsc -GR- -Oi -MT -Z7 -W4 -WX -wd4201 -FC -O2 +set CompileFlags=-EHsc -GR- -Oi -MT -Z7 -W4 -WX -wd4201 -FC -Od REM Include directories set IncludeFlags= diff --git a/dqn.h b/dqn.h index 4b9c681..4e39392 100644 --- a/dqn.h +++ b/dqn.h @@ -3951,13 +3951,22 @@ DQN_FILE_SCOPE i32 Dqn_I32ToWstr(i32 value, wchar_t *buf, i32 bufSize) // Convert a randomized u32 value to a float value x in the range 0.0f <= x // < 1.0f. Contributed by Jonatan Hedborg + +// NOTE: This is to abide to strict aliasing rules. +union DqnRndInternal_U32F32 +{ + u32 unsigned32; + f32 float32; +}; + FILE_SCOPE f32 DqnRnd_F32NormalizedFromU32Internal(u32 value) { u32 exponent = 127; u32 mantissa = value >> 9; - u32 result = (exponent << 23) | mantissa; - f32 fresult = *(f32 *)(&result); - return fresult - 1.0f; + + union DqnRndInternal_U32F32 uf; + uf.unsigned32 = (exponent << 23 | mantissa); + return uf.float32 - 1.0f; } FILE_SCOPE u64 DqnRnd_Murmur3Avalanche64Internal(u64 h) @@ -4145,6 +4154,7 @@ PERFORMANCE vs MSVC 2008 32-/64-bit (GCC is even slower than MSVC): #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmisleading-indentation" + #pragma GCC diagnostic ignored "-Wstrict-aliasing" #endif #include // for va_arg() diff --git a/dqn_unit_test.cpp b/dqn_unit_test.cpp index 6032fc6..cfde316 100644 --- a/dqn_unit_test.cpp +++ b/dqn_unit_test.cpp @@ -343,7 +343,7 @@ void StringsTest() char e[DQN_64BIT_NUM_MAX_STR_SIZE] = {}; Dqn_I64ToStr(SMALLEST_NUM, e, DQN_ARRAY_COUNT(e)); - DQN_ASSERT(DqnStr_Cmp(e, "-9223372036854775808") == 0); + DQN_ASSERT_MSG(DqnStr_Cmp(e, "-9223372036854775808") == 0, "e: %s", e); printf("StringsTest(): I64ToStr: Completed successfully\n"); } @@ -569,18 +569,17 @@ void RandomTest() PrintHeader("Random Number Generator Test"); DqnRandPCGState pcg; DqnRnd_PCGInit(&pcg); - for (i32 i = 0; i < 10; i++) + for (i32 i = 0; i < 1000000; i++) { i32 min = -100; - i32 max = 100000; + i32 max = 1000000000; i32 result = DqnRnd_PCGRange(&pcg, min, max); DQN_ASSERT(result >= min && result <= max); f32 randF32 = DqnRnd_PCGNextf(&pcg); DQN_ASSERT(randF32 >= 0.0f && randF32 <= 1.0f); - printf("RandomTest(): RndPCG: Completed successfully\n"); } - + printf("RandomTest(): RndPCG: Completed successfully\n"); printf("RandomTest(): Completed successfully\n"); } diff --git a/makefile b/makefile index 24d9329..33cd42a 100644 --- a/makefile +++ b/makefile @@ -1,3 +1,3 @@ all: dqn_unit_test.cpp mkdir -p bin - g++ -o bin/dqn_unit_test dqn_unit_test.cpp -lm -Wall -Werror -pthread -ggdb + g++ -o bin/dqn_unit_test dqn_unit_test.cpp -lm -Wall -Werror -pthread -ggdb -O3