how to distinguish whether the type is unsigned or not

B

baibaichen

hi,

consider the follow code:

#ifdef USE_UNSIGNED_INT
typedef unsigned int size;
#else
typedef unsigned int size;
#endif

latter in the program:
size i = XXX;
for (; i >0 ; i++) //problematic, if the i is the unsigned it!!!
{
}

is there any static assert way to distinguish whether the type is
unsigned or not? such as :

size i = XXX;
STATIC_ASSERT_IS_NOT_SIGNED(size);
for (; i >0 ; i++) {
}
thanks
 
B

baibaichen

sorry, the code should be:
size i = XXX;
for (; i >=0 ; i++) //problematic, if the i is the unsigned it!!!
{ }

thanks
 
J

Jack Klein

sorry, the code should be:
size i = XXX;
for (; i >=0 ; i++) //problematic, if the i is the unsigned it!!!
{ }

thanks

Assuming the value is in range:

for (int signed_i = i; i>= 0; i++)

But I question your original logic. Assuming 'i' is signed to start
with, are you planning on incrementing it until it overflows? That's
undefined behavior.
 
B

baibaichen

oops!! my mistake!

sorry, the code should be:
size i = XXX;
for (; i >=0 ; i--) //problematic, if the i is the unsigned it!!!
{ }

not i++
 
Y

yuvalif

I don't know if its in the standard, but you may use the following
underflow detection:

while(i >= 0)
{
....
if (i - 1 > i)
break; // underflow
else
--i;
}

BTW, if the type of "i" is defined by the preprocessor than there
should be a compilation warning for unsigned (in gcc its something like
"condition is allways true"), and you can have the preprocessor create
the correct code for you. If the type of "i" is defined by a template
parameter that is sometimes unsigned, than its a possible (again I'm
not sure its standard) solution.

Yuval.
 
D

David Harmon

On 21 Dec 2005 19:30:12 -0800 in comp.lang.c++, "baibaichen"
is there any static assert way to distinguish whether the type is
unsigned or not? such as :

This is not tough to do along the lines of the boost template
metaprogramming library... they supply BOOST_STATIC_ASSERT and e.g.
::boost::is_integral<T>::value which is a close example, but you
would have to extend it for signed and unsigned which they do not
quite cover.
http://www.boost.org
 
D

Dervish

Try this:
#define STATIC_ASSERT_IS_NOT_SIGNED(type) \
{ static const char someArray[(char)(type(-1) < type(1))]; }
 
N

Niklas Norrthon

baibaichen said:
hi,

consider the follow code:

#ifdef USE_UNSIGNED_INT
typedef unsigned int size;
#else
typedef unsigned int size;
#endif

latter in the program:
size i = XXX;
for (; i >0 ; i++) //problematic, if the i is the unsigned it!!!
{
}

is there any static assert way to distinguish whether the type is
unsigned or not? such as :

See the thread 'templates to generate compiler diagnostics' I
started last week. I had an example doing exactly what you
ask for. Someone mentioned BOOST_STATIC_ASSERT that did the
same thing, a bit more complicated than I did, but also
a bit more elegant.

/Niklas Norrthon
 
R

Robin

baibaichen 写é“:
hi,

consider the follow code:

#ifdef USE_UNSIGNED_INT
typedef unsigned int size;
#else
typedef unsigned int size;
#endif

latter in the program:
size i = XXX;
for (; i >0 ; i++) //problematic, if the i is the unsigned it!!!
{
}

is there any static assert way to distinguish whether the type is
unsigned or not? such as :

size i = XXX;
STATIC_ASSERT_IS_NOT_SIGNED(size);
for (; i >0 ; i++) {
}
thanks

-----------------------------------------------------------------------------------------------------
It's interesting, because I just joined a discussion similar to this
problem, but I'm not very sure whether answers given are what you want:
#define STATIC_ASSERT_IS_NOT_SIGNED(i) assert((i>=0)&&(~i>0))
or
#define STATIC_ASSERT_IS_NOT_SIGNED(i) assert((i-i-1)>0)

Just try it.

Regards,
Luo Bin (China)
 
N

Niklas Norrthon

David Harmon said:
On 21 Dec 2005 19:30:12 -0800 in comp.lang.c++, "baibaichen"


This is not tough to do along the lines of the boost template
metaprogramming library... they supply BOOST_STATIC_ASSERT and e.g.
::boost::is_integral<T>::value which is a close example, but you
would have to extend it for signed and unsigned which they do not
quite cover.

But that's trivial:

#include <boost/static_assert.hpp>
#include <limits>
#include "something_that_typedefs_size.h"

BOOST_STATIC_ASSERT(std::numeric_limits<size>::is_signed);

/Niklas Norrthon
 
D

ddh

template <class T>
struct Dummy;

template<>
struct Dummy<unsigned long>
{}

template<>
struct Dummy<unsigned int>
{}

template<>
struct Dummy<unsigned short>
{}

template<>
struct Dummy<unsigned char>
{}


#define STATIC_ASSERT_IS_NOT_SIGNED(type) sizeof(Dummy<type>)
 
M

Michiel.Salters

I don't know if its in the standard, but you may use the following
underflow detection:

while(i >= 0)
{
...
if (i - 1 > i)
break; // underflow
else
--i;
}

Definitely not in the standard. int underflow is UB just like int
overflow.
A completely valid implementation may define INT_MIN-1 as INT_MIN
and turn this into an infinite loop.

HTH,
Michiel Salters
 
M

Mike Wahler

baibaichen said:
hi,

consider the follow code:

#ifdef USE_UNSIGNED_INT
typedef unsigned int size;
#else
typedef unsigned int size;
#endif

latter in the program:
size i = XXX;
for (; i >0 ; i++) //problematic, if the i is the unsigned it!!!
{
}

is there any static assert way to distinguish whether the type is
unsigned or not? such as :

size i = XXX;
STATIC_ASSERT_IS_NOT_SIGNED(size);
for (; i >0 ; i++) {
}
thanks

if(std::numeric_limits<size>::is_signed)
std::cout << "signed\n";
else
std::cout << "unsigned\n";


'std::numeric_limits<>' is declared by <limits>

-Mike
 
D

David Harmon

On 22 Dec 2005 10:58:40 +0100 in comp.lang.c++, Niklas Norrthon
BOOST_STATIC_ASSERT(std::numeric_limits<size>::is_signed);

Thanks. I forgot to even look for that, having been thrown off in
the past by numeric_limits<T>::max() etc. which unfortunately cannot
be used in a static assert because it is a function call.

(I do not understand why max(), min() could not have been constants,
but undoubtedly the standards committee had some reason vastly more
important than making them checkable at compile time.)
 
D

David Harmon

On 22 Dec 2005 01:19:09 -0800 in comp.lang.c++, "Robin"
It's interesting, because I just joined a discussion similar to this
problem, but I'm not very sure whether answers given are what you want:
#define STATIC_ASSERT_IS_NOT_SIGNED(i) assert((i>=0)&&(~i>0))

But that has a runtime call to assert() and therefore cannot be a
static assert!
 
R

Richard Herring

oops!! my mistake!

sorry, the code should be:
size i = XXX;
for (; i >=0 ; i--) //problematic, if the i is the unsigned it!!!
{ }

Sorry to resurrect an old thread, but I think you're asking (and other
posters have answered) the wrong question. What I think you really want
is not "how do I distinguish between signed and unsigned?" but "how do I
write a loop that counts down to 0 inclusive, regardless of whether the
type is signed?"

Try this:

for (size i = something.size(); i-- > 0; /*nothing*/)
{
}

(note that what I've written as something.size() is equivalent to your
XXX + 1)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,436
Messages
2,571,696
Members
48,796
Latest member
Greg L.
Top