Boost logo

Boost :

From: Reece Dunn (msclrhd_at_[hidden])
Date: 2005-10-18 15:36:52


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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk