svn commit: r273734 - head/bin/dd

Bruce Evans brde at optusnet.com.au
Tue Oct 28 09:28:26 UTC 2014


On Tue, 28 Oct 2014, [utf-8] Dag-Erling Smørgrav wrote:

> Kurt Jaeger <pi at FreeBSD.org> writes:
>> Konstantin Belousov <kostikbel at gmail.com> writes:
>>> On Mon, Oct 27, 2014 at 11:38:17AM +0000, Kurt Jaeger wrote:
>>> /scratch/tmp/kib/src/bin/dd/args.c:192: warning: format '%jd' expects type 'intmax_t', but argument 3 has type 'int'
>> Thanks for the pointer. I'll take it up with the submitter.
>
> In an ideal world, you would have reviewed the patch before committing
> it...
>
>> I do not have a working arm setup right now.
>
> This is a bug on all platforms, and both clang and (recent) gcc should
> complain about it.  That printf() call will print garbage.

No, this is only a bug on 32-bit arches.  The is is SSIZE_MAX.  It has
type int on 32-bit arches and type long on 64-bit arches.  These types
are the same as ssize_t.  The compiler prints 'int' in the diagnostic
on 32-bit arches since it cannot see that the int is really an ssize_t.
SSIZE_MAX is defined as a literal constant with a correct type so that
it works in cpp expressions, so it doesn't have a cast to ssize_t.  At
least clang has more understanding of typedefed types then the C standard
requires, so it can distinguish identical types diagnostics.

Of course the patch is just broken in removing the casts of SSIZE_MAX.
They were carefully done to avoid precisely this portability bug.

Long long is an abomination, but you could find a lot of these portability
bugs on 64-bit arches by changing [u]intmax_t to [unsigned] <abomination>
while keeping [u]int64_t, [s]size_t and off_t as [unsigned] long.  Then
everything except [u]intmax_t and <abomination> would need to be cast to
print it using %j[du], the same as on 32-bit arches.  Only change this
transiently.  It breaks detection of the mismatch between <abomination>
and intmax_t.

Bruce


More information about the svn-src-head mailing list