
Scott Schurr wrote:
Markus Sch?pflin wrote:
For the next test, I changed struct test_values (in binary_int_test.cpp) to the following:
struct test_values { uint64_t hex_value; uint64_t bin_value; };
This additionally needs #include <boost/cstdint.hpp>.
When compiling and running this (on both 32 bit and 64 bit systems), I got the following error:
At test_array index 40 8a6c4e20 != ffffffff8a6c4e20 assertion "test_array[i].hex_value == test_array[i].bin_value" failed: file "../binary_int_test.cpp", line 118
I'm using the Microsoft 32-bit Compiler, Version 13.00.9466, and I'm running into two different problems with 64 bit values:
1. So far I've been unable to make Marcus's problem go away. With 32-bit values I was able to fix this up by forcing the underlying type that I write to my enums. When I try this same fix in 64-bits nothing gets better.
2. The worse problem is that binary value values larger than 32 bits (8 nibbles) get their upper nibbles truncated.
After a couple of tests it appears that, for this compiler, the largest supported enum value must fit in 32 bits. If that's correct, then my enum based calculations run out of steam on this compiler at 32 bits.
Have you tried an approach that does not use enums. You can either use a maximum-size integer: struct binary_int { #if BOOST_HAS_INT64 // Verify this static const uint64_t value = ...; #else static const unsigned long value = ...; #endif }; or you could do something like: template< int b1, int b2 > struct binary_int { typedef unsigned short type; static const type value = ...; }; template< int b1, int b2, ..., int b4 > struct binary_int { typedef unsigned long type; static const type value = ...; }; template< int b1, int b2, ..., int b8 > struct binary_int { typedef uint64_t type; static const type value = ...; }; Note that I haven't had chance to look at the implementation, so I could be hedding in completely the wrong direction. Also note that the standard says that it is perfectly legal to use static const integer_type val = some_static_expression; It is only for broken compilers (read VC6) where you need to use enum { val = some_static_expression }; If you want to retain the portability to older compilers, you can use the enum trick for < 32-bits and then do #if COMPILER_IS_NOT_BROKEN template< int b1, int b2, ..., int b8 > struct binary_int { typedef uint64_t type; static const type value = ...; }; #endif
Matt Calabrese's macro-based approach is looking more appealing, at least as far as 64-bit support goes.
At the moment :). - Reece