Gunnar Dalsnes wrote:
Suggested gcc/msvc portability macros:
#if defined(_MSC_VER)
#define MK_INT64(a) (a) #define MK_UINT64(a) (a)
Why not the explicit suffix (i.e. "(a##i64)" and "(a##ui64)")? Especially the latter is required to be able to create specifically an unsigned 64-bit integer.
__inline LARGE_INTEGER MK_LARGE_INTEGER(__int64 i)
If anything, "static __inline", but there are more problems with this as I'll explain below.
{ LARGE_INTEGER li; li.QuadPart = i; return li; }
#define LARGE_INTEGER_NULL MK_LARGE_INTEGER(0)
and this is the problem. It does not evaluate to a LARGE_INTEGER intitialized to the value zero at compile-time. To verify, just add
static const LARGE_INTEGER zero = MK_LARGE_INTEGER(0);
at file scope, and see the C compiler complain "initializer is not a constant".
From the looks of it, none of these problems are present in the GNUC path.
Another potential source of confusion could be the use of "NULL", which in the context of both C and C++ is carved in stone to mean a null-pointer value. What about the character 0 (zero)?
The initialization of a LARGE_INTEGER is indeed a problem, since it's an aggregate type, and I don't see a clean and portable solution to that problem. For the simple case of zero-initializing an external or static LARGE_INTEGER one can use something like
LARGE_INTEGER Li0 = { 0 };
but I have seen it suggested this might not be intended to work for variables with automatic storage duration.
-- /Mike