Where to check if type long long is defined? I wanna do something like this:
#ifdef LONGLONG
#define long_long long long
#else
#define long_long long
#endif
LLONG_MAX gives the maximum value representable by a long long; if your implementation doesn't support long long, it shouldn't define LLONG_MAX.
#include <limits.h>
#ifdef LLONG_MAX
#define long_long long long
#else
#define long_long long
#endif
This isn't a perfect solution. long long isn't standard in C++03, and long long has been around longer than C99, so it's possible (and likely) that a compiler could support long long but not define LLONG_MAX.
If you want an integer type with a specific size, you should use <stdint.h> if your implementation supports it. If your implementation doesn't support it, Boost has an implementation of it.
Rather than worry about whether or not a type with that name is defined, I'd #include <climits> and check whether or not you can find an integer type large enough for your intended use. (Although you could probably just check if LLONG_MAX is defined to find out if long long exists.)
Edit: Or, if you can assume C99 headers and types to be available, #include <cstdint.h> and use e.g. int64_t to get a 64-bit type or int_fast64_t to get a “fast” 64-bit type (by some compiler-specific definition of fast). Or intmax_t if you want the largest available type.
Related
I have a problem using atomicAdd under CUDA 7. atomicAdd is defined for "int", "unsigned int" and "unsigned long long int" stating it uses "the 32 or 64 bit value".
In our code we use uint32_t and uint64_t for safety. However gcc defines this in the following way:
#if __WORDSIZE == 64
typedef unsigned long int uint64_t;
#else
__extension__
typedef unsigned long long int uint64_t;
#endif
So when I pass an uint64_t to atomicAdd it complains because it is not defined for "unsigned long int".
Is it save to assume uint64_t == long long int for CUDA compilation as stated in the programming guide?
To answer that for future reference:
There are 2 options: Either use a typedef to define 64 bit cuda types like:
typedef long long int int64_cu
typedef unsigned long long int uint64_cu
And probably guard these by (boost-)static_asserts to be the same size(of)
Or as suggested by #Anastasiya Asadullayeva use a reinterpret_cast in the call which is better also guarded by a static_assert.
I need a way to get the largest type available on the target compiler architecture. I'd expect a define along the lines of:
#if defined PLATFORM_32BIT
#define LARGEST_UNSIGNED_TYPE uint32_t
#elseif defined PLATFORM_64BIT
#define LARGEST_UNSIGNED_TYPE uint64_t
#endif
Is there a standard C++ way to achieve this? Or do I need to roll my own?
If you can use uint64_t you should also be able to use uintmax_t.
Header <cstdint>in C++ (and <stdint.h> in C) already contains the following definitions
typedef signed integer type intmax_t;
and
typedef unsigned integer type uintmax_t;
Right now I'm working on a project that extensively uses 64bit unsigned integers in many parts of the code. So far we have only been compiling with gcc 4.6 but we are now porting some code to windows. It's crucial that these unsigned ints are 64bits wide. It has been suggested that we could use long long but it's not good if long long happens to be bigger than 64bits, we actually want to have a guarantee that it will be 64 bits and writing something like static_assert(sizeof(long long) == 8) seems to be a bit of a code smell.
What is the best way to define something like uint64 that will compile across both gcc and msvc without needing to have different code syntax used everywhere?
What about including cstdint and using std::uint64_t?
You can use boost:
The typedef int#_t, with # replaced by the width, designates a signed
integer type of exactly # bits; for example int8_t denotes an 8-bit
signed integer type. Similarly, the typedef uint#_t designates an
unsigned integer type of exactly # bits.
See: http://www.boost.org/doc/libs/1_48_0/libs/integer/doc/html/boost_integer/cstdint.html
Especially this header:
http://www.boost.org/doc/libs/1_48_0/boost/cstdint.hpp
This is what I do:
#ifndef u64
#ifdef WIN32
typedef unsigned __int64 u64;
#else // !WIN32
typedef unsigned long long u64;
#endif
#endif
On Windows you can use __int64, unsigned __int64, or typedefs: UINT64, INT64 etc.
Look at this
But yes, if code portability is concern, use standard typedefs, as suggested by others.
I would like to profit by int64_t for my int, when present in a c++98 or greater implementation (I know C++11 already provides a 64-bit int).
Is there a portable and generic way to check the presence of int64_t or - even better - any 64-bit-or-greater integer type available, as in:
#ifdef has_int64_t
typedef int64_t myint
#else
typedef int myint
#endif
//...code
myint a;
If possible the check should work for c++98, c++03 and c++11.
Pretty sure this should work using stdint.h:
#ifdef INT64_C
//...
#else
//...
#endif
The situation with stdint.h and the C++11 cstdint headers is rather tricky. Especially since they are missing on certain VS versions. The easiest route is certainly boost stdint.
I have some c(++) code that uses sprintf to convert a uint_64 to a string. This needs to be portable to both linux and Solaris.
On linux we use %ju, but there does not appear to be any equivalent on Solaris. The closest I can find is %lu, but this produces incorrect output. Some sample code:
#include <stdio.h>
#include <sys/types.h>
#ifdef SunOS
typedef uint64_t u_int64_t;
#endif
int main(int argc, char **argv) {
u_int64_t val = 123456789123L;
#ifdef SunOS
printf("%lu\n", val);
#else
printf("%ju\n", val);
#endif
}
On linux, the output is as expected; on Solaris 9 (don't ask), it's "28"
What can I use?
If you have have inttypes.h available you can use the macros it provides:
printf( "%" PRIu64 "\n", val);
Not pretty (I seem to be saying that a lot recently), but it works.
On a C99 compliant system:
#include <inttypes.h>
uint64_t big = ...;
printf("%" PRIu64 "\n", big);
See section 7.8 of the C99 standard.
The specifiers are {PRI,SCN}[diouxX]{N,LEASTN,MAX,FASTN,PTR}
Where PRI is for the printf() family, SCN is for the scanf() family, d and i for signed integral types; o,u,x,X are for unsigned integral types as octal, decimal, hex, and Hex; N is one of the supported widths; LEAST and FAST correspond to those modifiers; PTR is for intptr_t; and MAX is for intmax_t.
The answer depends on whether your code is actually C or C++. In C, you should be using an unsigned long long rather than another type (this is conformant to the current standard, and long long is pretty common as far as C99 support goes), appending ULL instead of L to your constant, and using (as has been mentioned) %llu as your specifier. If support for C99 doesn't exist, you may want to check the compiler documentation, as there is no other standard way to do it. long long is guarateed to be 64 bits at least.
You can use %llu for long long. However, this is not very portable either, because long long isn't guaranteed to be 64 bits. :-)
You can get uint64_t from stdint.h if you want to avoid the SunOS conditional typedef.