A few WARNS6 cleanups

Joerg Sonnenberger joerg at britannica.bec.de
Mon Jan 3 12:24:08 PST 2005


On Mon, Jan 03, 2005 at 11:40:00AM -0800, Chris Pressey wrote:
> /*
>  * Super block for an FFS file system.
>  */
> struct fs {
> 	...
> 	int32_t	 fs_size;		/* number of blocks in fs */
> 	int32_t	 fs_dsize;		/* number of data blocks in fs */
> 	int32_t	 fs_ncg;		/* number of cylinder groups */
> 	int32_t	 fs_bsize;		/* size of basic blocks in fs */
> 	int32_t	 fs_fsize;		/* size of frag blocks in fs */
> 	int32_t	 fs_frag;		/* number of frags in a block in fs */
> 	...
> 
> None of these can ever be below zero, but they all must be signed for
> the sake of compatibility.

The on-disk structure is not changed if any of this fields become
unsigned. The problem is that certain limitations might no longer apply,
e.g. overflow checks might not work any longer.

> In other words, snprintf can never return a negative number.  Yet its
> return value is signed.  This means that the fairly common idiom
> 
> 	if (snprintf(buf, sizeof(f), f, ...) > sizeof(f)) { err(); }

Actually snprintf and some other functions in the same league have a
fundamentally wrong return type. They should return size_t or ssize_t,
because sizeof(size_t) >= sizeof(int) and the number of bytes actually
writeable e.g. to a string is limited by (s)size_t. Yes, I consider this
a flaw in the standard.

A better example of where a cast is needed and the API is correct, is read.
E.g.
	if (read(0, buf, sizeof(buf)) != sizeof(buf)) {
		...
	}
generates a warning, because to allow error validation read returns
a signed size_t, but sizeof is unsigned.

To summarize this whole discussion, it can't be avoided to add casts,
but it is important to understand when casts are necessary and how
to correctly cast. For example, it is better to cast the sizeof(buf)
to ssize_t in the example above, because _we_ know that there won't be
any problem. It would be nice if GCC could automatically stop printing
warnings if a fixed integer can be representated as both or an unsigned
integer of a smaller type is compared to a greater signed type. The first
can be savely promoted to signed and the latter as well.

Joerg





More information about the Submit mailing list