Hi
I have a code as follow:

template<class T>
inline bool IsValidUnsignedLong(T n)
{
    return (T)(unsigned long) n == n;
}

When I pass -l to that function, it returns TRUE which it shouldn't since its not unsigned. Can anyone explain to me the reason behind this? why am I getting TRUE instead of FALSE. I know it has something to do with casting but I can't see/find the reason.

Thanks in advance.

--
Mark

Recommended Answers

All 4 Replies

You do a cast to unsigned int and then you cast it back to T . This kind of cast generally has undefined behavior, but it is defined that doing (T)(U)t for T t; should yield the same value as t . So, your code is merely checking a standard-defined behavior, if it didn't yield true, it means your compiler is broken.

Your implementation and your strategy for checking if a value is unsigned is not possible, it has too much undefined or implementation-defined behavior, and according to the standard, it shouldn't work in any case. You dangerously run into the possibility of overflow as well.

If you need a meta-function to determine if a type is unsigned or not, you should use the std::is_unsigned template. As in:

#include <type_traits>

template<class T>
inline 
constexpr bool IsValidUnsignedLong(T)
{
    return std::is_unsigned<T>::value;
}

i am not sure what's the deal with all this unsigned/signed issues, my guess is that has something to do with the fact that after it reaches it's top/bottom range, a variable starts 'resetting' from the other side(if you understand what i mean)
anyway, if you want a function to check for if a variable is unsigned long(or any other type) you could try this:

template<class T>
inline bool IsUnsigned(T n)
{
    return std::string(typeid(n).name( )) == std::string("unsigned long");
}

note you must

#include <string>
#include <typeinfo> // in my compiler i can skyp this include, so i am not sure it is necessarily

edit: mike just posted a message by the time i was writing mine, you can follow his method since is better(cleaner and less time consuming)

Thank you all for the help.

Now I understand whats going on.
Thank you both the tip on testing the unsigned. I assume that it should be hard to do the same thing in C, or I could be wrong.

--
Mani

Since C doesn't have templates, why would you want to check if a type is unsigned or not? You will always know the exact type of anything, so knowing if a type is unsigned or not is simply a matter of checking the documentation on the type in question. Also, because C doesn't have overloaded functions, it would be pretty hard to achieve this anyways.

The Boost is_unsigned template (compatible with C++03) is essentially implemented as a number of specialization of the template for each fundamental type with the value of true for those which are unsinged and false otherwise, and if you have a custom type that is unsigned, you just provide an additional specialization for your custom type.

In other words, there is no reliable way, via casts, to determine if a type is unsigned. Most integral casts involve a policy of "not changing the bits", so casting back and forth a value is not really going to work.

Besides using templates or compiler intrinsics (which is what std::is_unsigned uses), you could maybe succeed with this method:

template<class T>
inline 
bool IsValidUnsignedLong(T)
{
    return T(-1) > T(0);
}

//or as a template:
template <typename T>
struct is_unsigned {
  static const bool value = (T(-1) > T(0));
};

But I doubt that the above will always work. But if it does, it would work in C (assuming you don't know what type it is).

EDIT: I just looked up the C++ standard and it appears that std::is_unsigned is specified to be equivalent to checking T(-1) > T(0) (but it might still be implemented as specializations).

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.