This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/13295] New: for some integer types U, (~U(0)) < U(0) != U(~U(0)) < U(0)
- From: "gianni at mariani dot ws" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 4 Dec 2003 05:53:50 -0000
- Subject: [Bug c++/13295] New: for some integer types U, (~U(0)) < U(0) != U(~U(0)) < U(0)
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
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