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.