Re: [PATCH 7/7] asm-generic: suppress sparse warning in ioctl.h

From: Derek M Jones
Date: Fri Apr 04 2008 - 10:30:49 EST


Al,

* typedef *can* be variably-modified, but only in block scope.
Warning: this can get sticky for us - all sizes are evaluated when
typedef is reached. IOW,
typedef int a[n];
a x;
if (n++ == 5) {
a y;
int z[n];
}
will have size of y equal to that of x, but *not* equal to that of z.

An opportunity for Sparse to issue a warning :-)

Another thing to keep in mind is that sizeof(VLA) is not a constant
expression *and* that sizeof argument is evaluated. IOW, not only
sizeof(int [n = f()])
has side effects, but in
int (*p)[n];
...
sizeof(*(g(), p))
will have g() evaluated. Note that if p had been declared as
int (*p)[4];
the same sizeof() would *NOT* have called anything. This, BTW, is where
the rules for what an integer constant expression is are getting bloody
important:

Any side effect appearing in a sizeof operand ought to be flagged.
There are people out there who think that the side effects occur (even
in C90).

Sentence 1122: http://c0x.coding-guidelines.com/6.5.3.4.html
"If the type of the operand is a variable length array type, the operand is evaluated;"

But watch out for sentence 1584: http://c0x.coding-guidelines.com/6.7.5.2.html
"Where a size expression is part of the operand of a sizeof operator and
changing the value of the size expression would not affect the result of
the operator, it is unspecified whether or not the size expression is
evaluated."

int n = 1;
int f(void)
{
int (*p)[1 + (0 && n)];
return sizeof(*(g(), p));
}

_must_ call g() according to C99, while the same with
enum {n = 1;} must not, even though n won't be even looked at in either
case *and* any sane compiler will find return value of f() at compile
time, turning it to

Any sane compiler that performs the analysis needed to deduce that
the expression inside the parenthesis always evaluated to zero
will turn it into....

One more thing: use of sizeof(variably-modified type) may or may not
evaluate size expressions in there if they do not affect the result.
IOW, it's unspecified whether
sizeof(int (*)[n++])
increments n; different compilers are broken in different ways and it

This language feature came about because at least one vendor on the
WG14 committee had a compiler that optimized away subexpressions
within a sizeof that did not contribute to the result of the
evaluation. My attempt to stop the behavior being unspecified
did not succeed :-(

--
Derek M. Jones tel: +44 (0) 1252 520 667
Knowledge Software Ltd mailto:derek@xxxxxxxxxxxx
Applications Standards Conformance Testing http://www.knosof.co.uk

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/