/* type_s64.h Define 64-bit integer data types, based on user-supplied options of compiler-supplied #defines if available. In the 1990's (Metrowerks projects, notably Power MANDELZOOM) I used my C++ library "i64_o.c" to get 64-bit integers. PMZ is the only project I have that still uses it. Compiler-provided definitions can be seen with "show_predefs.h" or a command like: gcc -dM -E - < /dev/null | sort Here is a partial list of compiler defines that can be used to figure out the size of pointer and long. They are used like this: #if (defined(__foo__) && defined(__bar__)) width defines 64 _AIX && __64BIT__ 64 __hpux && __LP64__ 32 __linux__ && __i386__ 64 __linux__ && __ia64__ 64 __linux__ && __x86_64__ 32 __linux__ && __powerpc__ 64 __linux__ && __powerpc64__ 32 __linux__ && __s390__ 64 __linux__ && __s390x__ 64 __osf__ 64 sinix && __LP64__ 64 _WIN64 32 _WIN32 For Sun you need to test for either "sun" or "__sun", and if either of these is defined, include then test for "_LP64". To get a 64-bit int in Microsoft visual C++ (i.e. in both _WIN32 and _WIN64), you can use "__int64" and "unsigned __int64". To get 64-bit int in Linux (i.e. __linux__) and in MacOS X (i.e. __APPLE__ && __MACH__) you can include and then use "int64_t" and "uint64_t". Otherwise test the other combinations in the list above (e.g. __hpux && __LP64__) to find out if "long" is 64-bit, and if it isn't, use "long long" to get 64-bit. "long long" is part of the C99 standard; by extension GCC has provided it in C90 and C++ modes since the late 1990's. You can use #ifdef __GNUC__ followed by an #if expression including __GNUC__ and __GNUC_MINOR__ to determine if your specific GCC version includes it. REVISION HISTORY: 20191019 Use __int64 on Windows systems */ /* First check user-supplied options */ #ifdef LONGLONG_IS_S64 typedef signed long long int s64; typedef unsigned long long int u64; # define HAVE_S64 #elif LONG_IS_S64 typedef signed long int s64; typedef unsigned long int u64; # define HAVE_S64 #elif DUNDER_INT64_IS_S64 typedef __int64 s64; typedef unsigned __int64 u64; # define HAVE_S64 #endif /* Next check things defined by compilers. */ /* NOTE: Very early GCC probably does not provide long long. */ #ifdef __GNUC__ typedef signed long long int s64; typedef unsigned long long int u64; # define HAVE_S64 #endif /* Early Microsoft compilers definitely do not provide "long long". It is safe to use __int64 unless your MSFT compiler is so old that it doesn't provide any 64-bit int type, in which case it's hopeless. */ #if (defined(_WIN32) || defined(_WIN64)) # define DUNDER_INT64_IS_S64 #endif #ifndef HAVE_S64 # ifdef DUNDER_INT64_IS_S64 typedef __int64 s64; typedef unsigned __int64 u64; # define HAVE_S64 # endif #endif /* Last deperate effort to define something, if we weren't alredy able to figure it out */ #ifndef HAVE_S64 typedef signed long long int s64; typedef unsigned long long int u64; # define HAVE_S64 #endif /* This macro provides code that you can use at runtime (e.g. at the beginning of your main) to make sure s64 is actually 64 bits. It assumes is already included. We don't include stdio for you because perhaps you don't want to use this macro. */ #ifndef TYPE_S64_CHECK_SIZE # define TYPE_S64_CHECK_SIZE(procname) \ if (sizeof(s64) != 8) { \ printf("%s: s64 is not 8 bytes (got %d).\n", \ (procname), (int) sizeof(s64)); \ if (sizeof(long) == 8) { \ printf( \ " To fix this error, recompile with the flag -DLONG_IS_S64\n"); \ } else if (sizeof(long long) == 8) { \ printf( \ " To fix this error, recompile with the flag -DLONGLONG_IS_S64\n"); \ } else { \ printf( \ " (presently, sizeof(long)==%d and sizeof(long long)==%d)\n", \ (int) sizeof(long), (int) sizeof(long long)); \ } \ exit(-1); \ } #endif