I need to print a ULONGLONG value (unsigned __int64). What format should i use in printf ?
I found %llu in another question but they say it is for linux only.
Thanks for your help.
Using Google to search for “Visual Studio printf unsigned __int64” produces this page as the first result, which says you can use the prefix I64, so the format specifier would be %I64u.
%llu is the standard way to print unsigned long long, it's not just for Linux, it's actually in C99. So the problem is actually to use a C99-compatible compiler, i.e, not Visual Studio.
C99 7.19.6 Formatted input/output functions
ll(ell-ell) Specifies that a following d, i, o, u, x, or X conversion specifier applies to a
long long int or unsigned long long int argument; or that a following n conversion specifier applies to a pointer to along long int argument.
I recommend you use PRIu64 format specified from a standard C library. It was designed to provide users with a format specifier for unsigned 64-bit integer across different architectures.
Here is an example (in C, not C++):
#include <stdint.h> /* For uint64_t */
#include <inttypes.h> /* For PRIu64 */
#include <stdio.h> /* For printf */
#include <stdlib.h> /* For exit status */
int main()
{
uint64_t n = 1986;
printf("And the winning number is.... %" PRIu64 "!\n", n);
return EXIT_SUCCESS;
}
Printf has different format specifiers for unsigned long long depending on the compiler, I have seen %llu and %Lu. In general I would advice you to use std::cout and similar instead.
Here is a work around for HEX output
printf("%08X%08X", static_cast<UINT32>((u64>>32)&0xFFFFFFFF), static_cast<UINT32>(u64)&0xFFFFFFFF));
For guys who forget all the time like me,
If you use Visual Studio (MSVC),
%I64u for uint64_t (unsigned __int64)
%I64d for int64_t (__int64)
%Iu for size_t
You should check this MSDN for the details, or just this section :)
Related
I am trying to adapt an existing code to a 64 bit machine. The main problem is that in one function, the previous coder uses a void* argument that is converted into suitable type in the function itself. A short example:
void function(MESSAGE_ID id, void* param)
{
if(id == FOO) {
int real_param = (int)param;
// ...
}
}
Of course, on a 64 bit machine, I get the error:
error: cast from 'void*' to 'int' loses precision
I would like to correct this so that it still works on a 32 bit machine and as cleanly as possible. Any idea ?
I'd say this is the modern C++ way:
#include <cstdint>
void *p;
auto i = reinterpret_cast<std::uintptr_t>(p);
EDIT:
The correct type to the the Integer
So the right way to store a pointer as an integer is to use the uintptr_t or intptr_t types. (See also in cppreference integer types for C99).
These types are defined in <stdint.h> for C99 and in the namespace std for C++11 in <cstdint> (see integer types for C++).
C++11 (and onwards) Version
#include <cstdint>
std::uintptr_t i;
C++03 Version
extern "C" {
#include <stdint.h>
}
uintptr_t i;
C99 Version
#include <stdint.h>
uintptr_t i;
The correct casting operator
In C there is only one cast and using the C cast in C++ is frowned upon (so don't use it in C++). In C++ there are different types of casts, but reinterpret_cast is the correct cast for this conversion (see also here).
C++11 Version
auto i = reinterpret_cast<std::uintptr_t>(p);
C++03 Version
uintptr_t i = reinterpret_cast<uintptr_t>(p);
C Version
uintptr_t i = (uintptr_t)p; // C Version
Related Questions
What is uintptr_t data type
Use intptr_t and uintptr_t.
To ensure it is defined in a portable way, you can use code like this:
#if defined(__BORLANDC__)
typedef unsigned char uint8_t;
typedef __int64 int64_t;
typedef unsigned long uintptr_t;
#elif defined(_MSC_VER)
typedef unsigned char uint8_t;
typedef __int64 int64_t;
#else
#include <stdint.h>
#endif
Just place that in some .h file and include wherever you need it.
Alternatively, you can download Microsoft’s version of the stdint.h file from here or use a portable one from here.
'size_t' and 'ptrdiff_t' are required to match your architecture (whatever it is). Therefore, I think rather than using 'int', you should be able to use 'size_t', which on a 64 bit system should be a 64 bit type.
This discussion unsigned int vs size_t goes into a bit more detail.
Use uintptr_t as your integer type.
Several answers have pointed at uintptr_t and #include <stdint.h> as 'the' solution. That is, I suggest, part of the answer, but not the whole answer. You also need to look at where the function is called with the message ID of FOO.
Consider this code and compilation:
$ cat kk.c
#include <stdio.h>
static void function(int n, void *p)
{
unsigned long z = *(unsigned long *)p;
printf("%d - %lu\n", n, z);
}
int main(void)
{
function(1, 2);
return(0);
}
$ rmk kk
gcc -m64 -g -O -std=c99 -pedantic -Wall -Wshadow -Wpointer-arith \
-Wcast-qual -Wstrict-prototypes -Wmissing-prototypes \
-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE kk.c -o kk
kk.c: In function 'main':
kk.c:10: warning: passing argument 2 of 'func' makes pointer from integer without a cast
$
You will observe that there is a problem at the calling location (in main()) — converting an integer to a pointer without a cast. You are going to need to analyze your function() in all its usages to see how values are passed to it. The code inside my function() would work if the calls were written:
unsigned long i = 0x2341;
function(1, &i);
Since yours are probably written differently, you need to review the points where the function is called to ensure that it makes sense to use the value as shown. Don't forget, you may be finding a latent bug.
Also, if you are going to format the value of the void * parameter (as converted), look carefully at the <inttypes.h> header (instead of stdint.h — inttypes.h provides the services of stdint.h, which is unusual, but the C99 standard says [t]he header <inttypes.h> includes the header <stdint.h> and extends it with
additional facilities provided by hosted implementations) and use the PRIxxx macros in your format strings.
Also, my comments are strictly applicable to C rather than C++, but your code is in the subset of C++ that is portable between C and C++. The chances are fair to good that my comments apply.
#include <stdint.h>
Use uintptr_t standard type defined in the included standard header file.
I came across this question while studying the source code of SQLite.
In the sqliteInt.h, there is a paragraph of code defined a macro convert between integer and pointer. The author made a very good statement first pointing out it should be a compiler dependent problem and then implemented the solution to account for most of the popular compilers out there.
#if defined(__PTRDIFF_TYPE__) /* This case should work for GCC */
# define SQLITE_INT_TO_PTR(X) ((void*)(__PTRDIFF_TYPE__)(X))
# define SQLITE_PTR_TO_INT(X) ((int)(__PTRDIFF_TYPE__)(X))
#elif !defined(__GNUC__) /* Works for compilers other than LLVM */
# define SQLITE_INT_TO_PTR(X) ((void*)&((char*)0)[X])
# define SQLITE_PTR_TO_INT(X) ((int)(((char*)X)-(char*)0))
#elif defined(HAVE_STDINT_H) /* Use this case if we have ANSI headers */
# define SQLITE_INT_TO_PTR(X) ((void*)(intptr_t)(X))
# define SQLITE_PTR_TO_INT(X) ((int)(intptr_t)(X))
#else /* Generates a warning - but it always works */
# define SQLITE_INT_TO_PTR(X) ((void*)(X))
# define SQLITE_PTR_TO_INT(X) ((int)(X))
#endif
And here is a quote of the comment for more details:
/*
** The following macros are used to cast pointers to integers and
** integers to pointers. The way you do this varies from one compiler
** to the next, so we have developed the following set of #if statements
** to generate appropriate macros for a wide range of compilers.
**
** The correct "ANSI" way to do this is to use the intptr_t type.
** Unfortunately, that typedef is not available on all compilers, or
** if it is available, it requires an #include of specific headers
** that vary from one machine to the next.
**
** Ticket #3860: The llvm-gcc-4.2 compiler from Apple chokes on
** the ((void*)&((char*)0)[X]) construct. But MSVC chokes on ((void*)(X)).
** So we have to define the macros in different ways depending on the
** compiler.
*/
Credit goes to the committers.
The best thing to do is to avoid converting from pointer type to non-pointer types.
However, this is clearly not possible in your case.
As everyone said, the uintptr_t is what you should use.
This link has good info about converting to 64-bit code.
There is also a good discussion of this on comp.std.c
I think the "meaning" of void* in this case is a generic handle.
It is not a pointer to a value, it is the value itself.
(This just happens to be how void* is used by C and C++ programmers.)
If it is holding an integer value, it had better be within integer range!
Here is easy rendering to integer:
int x = (char*)p - (char*)0;
It should only give a warning.
Since uintptr_t is not guaranteed to be there in C++/C++11, if this is a one way conversion you can consider uintmax_t, always defined in <cstdint>.
auto real_param = reinterpret_cast<uintmax_t>(param);
To play safe, one could add anywhere in the code an assertion:
static_assert(sizeof (uintmax_t) >= sizeof (void *) ,
"No suitable integer type for conversion from pointer type");
With C++11, For what it's worth, suppose you don't have any headers, then define:
template<bool B, class T, class F> struct cond { typedef T type; };
template<class T, class F> struct cond<false, T, F> { typedef F type;};
static constexpr unsigned int PS = sizeof (void *);
using uintptr_type = typename cond<
PS==sizeof(unsigned short), unsigned short ,
typename cond<
PS==sizeof(unsigned int), unsigned int,
typename cond<
PS==sizeof(unsigned long), unsigned long, unsigned long long>::type>::type>::type;
After that you can do the following:
static uintptr_type ptr_to_int(const void *pointer) {
return reinterpret_cast<uintptr_type>(pointer);
}
static void *int_to_ptr(uintptr_type integer) {
return reinterpret_cast<void *>(integer);
}
I already used boost::format in many case but I found one for which the windows implementation doesn't react as I expected because it throw an exception
boost::bad_format_string: format-string is ill-formed
I use macro to define hexa number output format for different platform:
#if (defined(WIN32) || defined(WIN64))
#define FORMATUI64X_09 "%09I64X"
#define FORMATUI64X_016 "%016I64X"
#else
#if defined __x86_64__
#define FORMATUI64X_09 "%09lX"
#define FORMATUI64X_016 "%016lX"
#else
#define FORMATUI64X_09 "%09llX"
#define FORMATUI64X_016 "%016llX"
#endif
#endif
and call format like below:
string msg = (boost::format("0x"FORMATUI64X_016"(hex) \t %i \t %d \t %s \t %i\t ") % an uint64_t % an int % an uint % a char* % an uint).str();
Remark that I use a syntax working perfectly with a 'fprintf'.
I suppose that it come from the 'uint64_t' format as an hexa, but do you know to write the same line in a way it will work for all platform ?
I64X is not a valid format specification for boost::format (it's Microsoft-specific). The format specification types are not platform-specific. Boost does not use the [sf]printf routines provided by your implementation's runtime, which is why the fact that it works with Visual Studio's fprintf doesn't really affect what boost::format supports. You should be using either %lX or %llX, as your non-Windows clause is doing.
I would probably just use %llX everywhere and cast output variables to long long, e.g.:
static_assert(sizeof(unsigned long long) >= sizeof(uint64_t), "long long must be >= 64 bits");
auto s = (boost::format("0x%016llx") % static_cast<unsigned long long>(u64)).str();
This should work anywhere that unsigned long long is sufficient to represent uint64_t, and you can add a static assertion (as shown) to ensure that.
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 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.
I am trying to adapt an existing code to a 64 bit machine. The main problem is that in one function, the previous coder uses a void* argument that is converted into suitable type in the function itself. A short example:
void function(MESSAGE_ID id, void* param)
{
if(id == FOO) {
int real_param = (int)param;
// ...
}
}
Of course, on a 64 bit machine, I get the error:
error: cast from 'void*' to 'int' loses precision
I would like to correct this so that it still works on a 32 bit machine and as cleanly as possible. Any idea ?
I'd say this is the modern C++ way:
#include <cstdint>
void *p;
auto i = reinterpret_cast<std::uintptr_t>(p);
EDIT:
The correct type to the the Integer
So the right way to store a pointer as an integer is to use the uintptr_t or intptr_t types. (See also in cppreference integer types for C99).
These types are defined in <stdint.h> for C99 and in the namespace std for C++11 in <cstdint> (see integer types for C++).
C++11 (and onwards) Version
#include <cstdint>
std::uintptr_t i;
C++03 Version
extern "C" {
#include <stdint.h>
}
uintptr_t i;
C99 Version
#include <stdint.h>
uintptr_t i;
The correct casting operator
In C there is only one cast and using the C cast in C++ is frowned upon (so don't use it in C++). In C++ there are different types of casts, but reinterpret_cast is the correct cast for this conversion (see also here).
C++11 Version
auto i = reinterpret_cast<std::uintptr_t>(p);
C++03 Version
uintptr_t i = reinterpret_cast<uintptr_t>(p);
C Version
uintptr_t i = (uintptr_t)p; // C Version
Related Questions
What is uintptr_t data type
Use intptr_t and uintptr_t.
To ensure it is defined in a portable way, you can use code like this:
#if defined(__BORLANDC__)
typedef unsigned char uint8_t;
typedef __int64 int64_t;
typedef unsigned long uintptr_t;
#elif defined(_MSC_VER)
typedef unsigned char uint8_t;
typedef __int64 int64_t;
#else
#include <stdint.h>
#endif
Just place that in some .h file and include wherever you need it.
Alternatively, you can download Microsoft’s version of the stdint.h file from here or use a portable one from here.
'size_t' and 'ptrdiff_t' are required to match your architecture (whatever it is). Therefore, I think rather than using 'int', you should be able to use 'size_t', which on a 64 bit system should be a 64 bit type.
This discussion unsigned int vs size_t goes into a bit more detail.
Use uintptr_t as your integer type.
Several answers have pointed at uintptr_t and #include <stdint.h> as 'the' solution. That is, I suggest, part of the answer, but not the whole answer. You also need to look at where the function is called with the message ID of FOO.
Consider this code and compilation:
$ cat kk.c
#include <stdio.h>
static void function(int n, void *p)
{
unsigned long z = *(unsigned long *)p;
printf("%d - %lu\n", n, z);
}
int main(void)
{
function(1, 2);
return(0);
}
$ rmk kk
gcc -m64 -g -O -std=c99 -pedantic -Wall -Wshadow -Wpointer-arith \
-Wcast-qual -Wstrict-prototypes -Wmissing-prototypes \
-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE kk.c -o kk
kk.c: In function 'main':
kk.c:10: warning: passing argument 2 of 'func' makes pointer from integer without a cast
$
You will observe that there is a problem at the calling location (in main()) — converting an integer to a pointer without a cast. You are going to need to analyze your function() in all its usages to see how values are passed to it. The code inside my function() would work if the calls were written:
unsigned long i = 0x2341;
function(1, &i);
Since yours are probably written differently, you need to review the points where the function is called to ensure that it makes sense to use the value as shown. Don't forget, you may be finding a latent bug.
Also, if you are going to format the value of the void * parameter (as converted), look carefully at the <inttypes.h> header (instead of stdint.h — inttypes.h provides the services of stdint.h, which is unusual, but the C99 standard says [t]he header <inttypes.h> includes the header <stdint.h> and extends it with
additional facilities provided by hosted implementations) and use the PRIxxx macros in your format strings.
Also, my comments are strictly applicable to C rather than C++, but your code is in the subset of C++ that is portable between C and C++. The chances are fair to good that my comments apply.
#include <stdint.h>
Use uintptr_t standard type defined in the included standard header file.
I came across this question while studying the source code of SQLite.
In the sqliteInt.h, there is a paragraph of code defined a macro convert between integer and pointer. The author made a very good statement first pointing out it should be a compiler dependent problem and then implemented the solution to account for most of the popular compilers out there.
#if defined(__PTRDIFF_TYPE__) /* This case should work for GCC */
# define SQLITE_INT_TO_PTR(X) ((void*)(__PTRDIFF_TYPE__)(X))
# define SQLITE_PTR_TO_INT(X) ((int)(__PTRDIFF_TYPE__)(X))
#elif !defined(__GNUC__) /* Works for compilers other than LLVM */
# define SQLITE_INT_TO_PTR(X) ((void*)&((char*)0)[X])
# define SQLITE_PTR_TO_INT(X) ((int)(((char*)X)-(char*)0))
#elif defined(HAVE_STDINT_H) /* Use this case if we have ANSI headers */
# define SQLITE_INT_TO_PTR(X) ((void*)(intptr_t)(X))
# define SQLITE_PTR_TO_INT(X) ((int)(intptr_t)(X))
#else /* Generates a warning - but it always works */
# define SQLITE_INT_TO_PTR(X) ((void*)(X))
# define SQLITE_PTR_TO_INT(X) ((int)(X))
#endif
And here is a quote of the comment for more details:
/*
** The following macros are used to cast pointers to integers and
** integers to pointers. The way you do this varies from one compiler
** to the next, so we have developed the following set of #if statements
** to generate appropriate macros for a wide range of compilers.
**
** The correct "ANSI" way to do this is to use the intptr_t type.
** Unfortunately, that typedef is not available on all compilers, or
** if it is available, it requires an #include of specific headers
** that vary from one machine to the next.
**
** Ticket #3860: The llvm-gcc-4.2 compiler from Apple chokes on
** the ((void*)&((char*)0)[X]) construct. But MSVC chokes on ((void*)(X)).
** So we have to define the macros in different ways depending on the
** compiler.
*/
Credit goes to the committers.
The best thing to do is to avoid converting from pointer type to non-pointer types.
However, this is clearly not possible in your case.
As everyone said, the uintptr_t is what you should use.
This link has good info about converting to 64-bit code.
There is also a good discussion of this on comp.std.c
I think the "meaning" of void* in this case is a generic handle.
It is not a pointer to a value, it is the value itself.
(This just happens to be how void* is used by C and C++ programmers.)
If it is holding an integer value, it had better be within integer range!
Here is easy rendering to integer:
int x = (char*)p - (char*)0;
It should only give a warning.
Since uintptr_t is not guaranteed to be there in C++/C++11, if this is a one way conversion you can consider uintmax_t, always defined in <cstdint>.
auto real_param = reinterpret_cast<uintmax_t>(param);
To play safe, one could add anywhere in the code an assertion:
static_assert(sizeof (uintmax_t) >= sizeof (void *) ,
"No suitable integer type for conversion from pointer type");
With C++11, For what it's worth, suppose you don't have any headers, then define:
template<bool B, class T, class F> struct cond { typedef T type; };
template<class T, class F> struct cond<false, T, F> { typedef F type;};
static constexpr unsigned int PS = sizeof (void *);
using uintptr_type = typename cond<
PS==sizeof(unsigned short), unsigned short ,
typename cond<
PS==sizeof(unsigned int), unsigned int,
typename cond<
PS==sizeof(unsigned long), unsigned long, unsigned long long>::type>::type>::type;
After that you can do the following:
static uintptr_type ptr_to_int(const void *pointer) {
return reinterpret_cast<uintptr_type>(pointer);
}
static void *int_to_ptr(uintptr_type integer) {
return reinterpret_cast<void *>(integer);
}