This is the mail archive of the gcc-help@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]

Re: Size of C/C++ data type from GNU GCC/g++ compiled ELF 64-bit LSB executable, AMD x86-64 vs. ELF 32-bit LSB executable, Intel 80386


Hi Tom,

As Brian pointed out, it is buggy to assume any given byte sizes of
integers on different platforms, compilers etc.

However, as you are in C++ land anyway, I'd recommend to use a simple
template program to let the compiler create the correct Int8, Int16,
Int32 and so on typedefs for you. Take a look at the attached code.

Daniel
// The only assumption we make is that a character contains 1 byte and a byte is a unit for 8 bits
#define CHAR_BIT 8

namespace internal {
	class ERROR_inttype_not_available
	{
		ERROR_inttype_not_available();
	};

	template< bool FIRST, class A, class B > struct select
	{
		typedef A T;
	};
	template< class A, class B > struct select< false, A, B >
	{
		typedef B T;
	};
	
}	// namespace internal

// Retrieves a signed/unsigned integer type with sizeof( T ) == BYTES
template< unsigned BYTES, bool SIGNED >
struct int_t
{
	typedef typename internal::select< sizeof( signed char ) * CHAR_BIT == 8 * BYTES,  signed char,
		    typename internal::select< sizeof( signed short ) * CHAR_BIT == 8 * BYTES, signed short,
			typename internal::select< sizeof( signed int ) * CHAR_BIT == 8 * BYTES, signed int,
			typename internal::select< sizeof( signed long ) * CHAR_BIT == 8 * BYTES, signed long,
			typename internal::select< sizeof( signed long long ) * CHAR_BIT == 8 * BYTES, signed long long,
			internal::ERROR_inttype_not_available >::T >::T >::T >::T >::T T;
};
template< unsigned BYTES >
struct int_t< BYTES, false>
{
	typedef typename internal::select< sizeof( unsigned char ) * CHAR_BIT == 8 * BYTES, unsigned char,
		    typename internal::select< sizeof( unsigned short ) * CHAR_BIT == 8 * BYTES, unsigned short,
			typename internal::select< sizeof( unsigned int ) * CHAR_BIT == 8 * BYTES, unsigned int,
			typename internal::select< sizeof( unsigned long ) * CHAR_BIT == 8 * BYTES, unsigned long,
			typename internal::select< sizeof( unsigned long long ) * CHAR_BIT == 8 * BYTES, unsigned long long,
			internal::ERROR_inttype_not_available >::T >::T >::T >::T >::T T;
};

// Retrieves the smallest unsigned integer type with sizeof( T ) >= BYTES
template< unsigned BYTES >
struct uint_t_min
{
	typedef typename internal::select< sizeof( unsigned char ) * CHAR_BIT >= 8 * BYTES, unsigned char,
		    typename internal::select< sizeof( unsigned short ) * CHAR_BIT >= 8 * BYTES, unsigned short,
			typename internal::select< sizeof( unsigned int ) * CHAR_BIT >= 8 * BYTES, unsigned int,
			typename internal::select< sizeof( unsigned long ) * CHAR_BIT >= 8 * BYTES, unsigned long,
			typename internal::select< sizeof( unsigned long long ) * CHAR_BIT >= 8 * BYTES, unsigned long long,
			internal::ERROR_inttype_not_available >::T >::T >::T >::T >::T T;
};



// Machine independent definition of sized integer types
typedef int_t< 1, true >::T		Int8;
typedef int_t< 2, true >::T		Int16;
typedef int_t< 4, true >::T		Int32;
typedef int_t< 8, true >::T		Int64;
typedef int_t< 1, false >::T	UInt8;
typedef int_t< 2, false >::T	UInt16;
typedef int_t< 4, false >::T	UInt32;
typedef int_t< 8, false >::T	UInt64;


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