This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/13295] New: for some integer types U, (~U(0)) < U(0) != U(~U(0)) < U(0)


It seems to be that constant expressions in templates involvoing ~T(0) for
unsigned char and unsigned short result in strange behaviour where:

(~U(0)) is not the same as U(~U(0))

see below:

Here is the test code results:

test for : signed char - OK
test for : char - OK
test for : short - OK
test for : int - OK
test for : long - OK
test for : long long - OK
test for : unsigned char - Failed
test for : unsigned short - Failed
test for : unsigned int - OK
test for : unsigned long - OK
test for : unsigned long long - OK

template <typename U>
struct type_tester
{
    // is_signed and is_signed_cast should theoretically be identical
    // ~U(0) and U(~U(0)) should be identical - for unsigned short
    // unsigned and char this seems not to be the case on gcc 3.3.1
    
    static const bool is_signed = (~U(0)) < U(0);
    static const bool is_signed_cast = U(~U(0)) < U(0);
};

//
// test code
#include <typeinfo>

template <typename U> struct type_namer
{ static const char * name; };

template <typename U>
const char * type_namer<U>::name = typeid(U).name();

// macro to create specialization
#define make_namer(A) \
template <> struct type_namer<A> \
{ static const char * name; }; \
template <> const char * type_namer<A>::name = #A; \
// end

make_namer(signed char)
make_namer(char)
make_namer(short)
make_namer(int)
make_namer(long)
make_namer(long long)
make_namer(unsigned char)
make_namer(unsigned short)
make_namer(unsigned int)
make_namer(unsigned long)
make_namer(unsigned long long)

#include <iostream>

//
// template function to run test
//
template <typename U>
void show()
{
    std::cout << "test for : " << type_namer<U>::name << " - ";

    std::cout << (
        ( type_tester<U>::is_signed != type_tester<U>::is_signed_cast )
        ? "Failed"
        : "OK"
    );
    
    std::cout << "\n";
}

//
// test all integer types.
//
int main()
{
    show<signed char>();
    show<char>();
    show<short>();
    show<int>();
    show<long>();
    show<long long>();
    show<unsigned char>();
    show<unsigned short>();
    show<unsigned int>();
    show<unsigned long>();
    show<unsigned long long>();
}

-- 
           Summary: for some integer types U, (~U(0)) < U(0) != U(~U(0)) <
                    U(0)
           Product: gcc
           Version: 3.3.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: gianni at mariani dot ws
                CC: gcc-bugs at gcc dot gnu dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13295


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]