Coding standards for 32/64-bits data

Bron Gondwana brong at fastmail.fm
Thu Jul 7 02:08:32 EDT 2011


Sending back to the list for general interest.

On Wed, Jul 06, 2011 at 05:03:22PM -0700, Greg A. Woods wrote:
> My posts don't seem to be going through to the list, and the list
> manager hasn't responded yet to my query as to why, so I thought I'd
> forward my reply to you directly:

Dave is away on holiday this week.  Your replies won't be coming
through because you are sending from a different address than
the one which is subscribed to the list.

> At Fri, 01 Jul 2011 17:05:41 +0900, "OBATA Akio" <obata at lins.jp> wrote:
> Subject: Re: Coding standards for 32/64-bits data
> > 
> > For printf format, how about to detect it in configure script?
> > 
> >  if (sizeof(time_t) == sizeof(unsigned long long))
> >      #define TIME_T_FMT "%llu"
> >  else
> >      #define TIME_T_FMT "%lu"
> 
> There doesn't seem to be huge consensus out there, but I would lean
> strongly towards NOT including the "%" character in such a definition.

imap/quota.h:61:#define UQUOTA_T_FMT     "%llu"
imap/quota.h:62:#define QUOTA_T_FMT      "%lld"
imap/quota.h:63:#define QUOTA_REPORT_FMT "%8llu"
lib/util.h:71:#define MODSEQ_FMT "%llu"
config.h:567:#define SIZE_T_FMT "%u"
config.h:569:#define SIZE_T_FMT "%lu"
config.h:571:#define SIZE_T_FMT "%llu"
config.h:577:#define OFF_T_FMT "%ld"
config.h:580:#define OFF_T_FMT "%lld"

We'd have to clean up pre-existing code, but that's OK.

> 	PRId32 considered harmful:
> 
> In order to avoid stupid warnings from some versions of GCC (and perhaps
> other compilers) on some types of systems you will still have to cast
> time_t to the appropriate int*_t type:
> 
>        time_t t = 0;
> 
>        printf("%" PRIdTIME "\n", (INT_TIME_T) t);

Yeah, that's messy.  The alternative is to not be printing time_t
values so much.  It's mostly in syslog statements for errors that
we do so right now.

> I've also seen it suggested that _every_ non-base-integer type _always_
> be cast to [u]intmax_t and printed using PRI[ud]MAX:
> 
> 	printf("%" PRIuMAX, (uintmax_t) ival);
> 	printf("%" PRIdMAX, (intmax_t) ival); /* for signed values */
> 
> The extra heavy lifting by printf() is trivial compared to the
> programmer overhead of trying to define and use the right PRI* macros.

Makes sense.

> Too bad printf(3) et al don't have format flag akin to '*' which allows
> you to pass the sizeof() and the signedness of an integer type to it so
> that you don't have to hard-code the integer size in the format
> string....
> 
> 	int128_t foo = -1;
> 	uint64_t ubar = 1;
> 
> 	#define issigned(v)	(((typeof(v)) -1 < 0) ? true : false)
> 	#define INTPARAM(v)	issigned(v), sizeof(v), v
> 
> 	printf("%Sd %Su\n", INTPARAM(foo), INTPARAM(ubar));
> 
> Too bad C99 invented some useless incompatible things, but didn't do
> something cool like this.

Yes - it's one of those frustrating little corners of C.

cout << v << endl;

Bron ( if only they had stopped there ;) )


More information about the Cyrus-devel mailing list