How would you write (in C/C++) a macro which tests if an integer type (given as a parameter) is signed or unsigned?
#define is_this_type_signed (my_type) ...
How would you write (in C/C++) a macro which tests if an integer type (given as a parameter) is signed or unsigned?
#define is_this_type_signed (my_type) ...
In C++, use std::numeric_limits<type>::is_signed
.
#include <limits>
std::numeric_limits<int>::is_signed - returns true
std::numeric_limits<unsigned int>::is_signed - returns false
See http://msdn.microsoft.com/en-us/library/85084kd6(VS.80).aspx.
If what you want is a simple macro, this should do the trick:
#define is_type_signed(my_type) (((my_type)-1) < 0)
For c++, there is boost::is_unsigned<T>. I'm curious why you need it though, there are few good reasons IMHO.
Your requirement isn't exactly the best, but if you'd like to hack together a define, one option could be:
#define is_numeric_type_signed(typ) ( (((typ)0 - (typ)1)<(typ)0) && (((typ)0 - (typ)1) < (typ)1) )
However, this isn't considered nice or portable by any means.
I was actually just wondering the same thing earlier today. The following seems to work:
#define is_signed(t) ( ((t)-1) < 0 )
I tested with:
#include <stdio.h>
#define is_signed(t) ( ((t)-1) < 0 )
#define psigned(t) printf( #t " is %s\n", is_signed(t) ? "signed" : "unsigned" );
int
main(void)
{
psigned( int );
psigned( unsigned int );
}
which prints:
int is signed
unsigned int is unsigned
You could do this better with a template function, less macro nasty business.
template <typename T>
bool IsSignedType()
{
// A lot of assumptions on T here
T instanceAsOne = 1;
if (-instanceAsOne > 0)
{
return true;
}
else
{
return false;
}
}
Forgive the formatting...
I would try this out and see if it works...
In C++ you can do:
bool is_signed = std::numeric_limits<typeof(some_integer_variable)>::is_signed;
numeric_limits is defined in the <limits> header.
In C, you can't write a macro that works on as-yet unknown typedef's of fundamental integer types.
In C++, you can as long as your type is a fundamental integer type or a typedef of a fundamental integer type. Here's what you'd do in C++:
template <typename T>
struct is_signed_integer
{
static const bool value = false;
};
template <>
struct is_signed_integer<int>
{
static const bool value = true;
};
template <>
struct is_signed_integer<short>
{
static const bool value = true;
};
template <>
struct is_signed_integer<signed char>
{
static const bool value = true;
};
template <>
struct is_signed_integer<long>
{
static const bool value = true;
};
// assuming your C++ compiler supports 'long long'...
template <>
struct is_signed_integer<long long>
{
static const bool value = true;
};
#define is_this_type_signed(my_type) is_signed_integer<my_type>::value
If you want a macro then this should do the trick:
#define IS_SIGNED( T ) (((T)-1)<0)
Basically, cast -1 to your type and see if it's still -1. In C++ you don't need a macro. Just #include <limits>
and:
bool my_type_is_signed = std::numeric_limits<my_type>::is_signed;
Althout typeof
is not legal C++ at the moment, you can use template deduction instead. See sample code below:
#include <iostream>
#include <limits>
template <typename T>
bool is_signed(const T& t)
{
return std::numeric_limits<T>::is_signed;
}
int main()
{
std::cout <<
is_signed(1) << " " <<
is_signed((unsigned char) 0) << " " <<
is_signed((signed char) 0) << std::endl;
}
This code will print
1 0 1