Comment 4 for bug 1740426

Revision history for this message
Andrew Johnson (anj) wrote :

The epics integer types from epicsTypes.h are the same on all architectures:

typedef char epicsInt8;
typedef unsigned char epicsUInt8;
typedef short epicsInt16;
typedef unsigned short epicsUInt16;
typedef int epicsInt32;
typedef unsigned int epicsUInt32;
typedef long long epicsInt64;
typedef unsigned long long epicsUInt64;

Because of the promotion rules these should use the unmodified printf() format specifiers %d/i/o/u/x except for the 64-bit types which need the %ll modifier, even when building for Windows. The Windows C runtime library has supported %lld since Windows versions after XP, but GCC has taken a while to catch up and may still be expecting %I64d so could generate printf-format warnings. We added -Wno-format to silence them for MinGW builds recently (after the 3.15.7 and 7.0.3.1 releases), but I just discovered that we can define __USE_MINGW_ANSI_STDIO instead which seems to be better (I will make that change).

Note that the stdint.h types such as int32_t might /not/ map the same way as the epics types depending on how the header defines them and whether long is 32 or 64-bits on that architecture — int32_t might be either int or long on ILP32 architectures, so GCC might expect %d or %ld for it. That's why I avoid using those types myself (and the fact that Wind River only added stdint.h in VxWorks 6.9).

The problem is therefore just size_t, which may need to be %lu or %zu depending on the architecture (I'm assuming all 64-bit arch's can handle %z). There is unfortunately no standard PRIuXXX macro for size_t, presumably because %z had already taken care of that.

If we define a macro PRIuSIZE or EPRIuSIZE in Base, most support modules wouldn't be able to rely on it since they generally have to build with older Base versions as well, so they'd end up having to do something like this too:

#ifndef EPRIuSIZE
# if defined(vxWorks)
# define EPRIuSIZE "lu"
# else
# define EPRIuSIZE "zu"
# endif
#endif

That ought to be sufficient for current architectures. but would need to be longer to support VS2010. If VxWorks 7 adds support for %z that difference would be handled in a newer version of Base anyway, so EPRIuSIZE would be correctly defined by that new Base already.

I find these printf() macros ugly and might not use this one myself, but I agree that we should probably provide and document it. Questions:

1. Which header should we define this in? The C99 standard macros are found in inttypes.h; epicsTypes.h is one possibility, although that has nothing to do with size_t. epicsStdio.h?

2. What name should we use? EPRIuSIZE, PRIuSIZE, PRIuS, ...? Do we need any non-'u' versions, say an 'x' version?

Did I miss anything?