cppcheck sept 18 redux
david at l8s.co.uk
Tue Sep 22 12:28:10 CDT 2009
On Tue, Sep 22, 2009 at 02:56:05AM -0400, Mike Kaplinskiy wrote:
> On Tue, Sep 22, 2009 at 1:09 AM, Vitaliy Margolen
> <wine-devel at kievinfo.com> wrote:
> > Ben Klein wrote:
> >> The question remains, how exactly does
> >> FIELD_OFFSET work, and does it end up dereferencing ca?
> > It does pointer arithmetic and does not dereference anything. "ca" is the
> > same as "(ca + 5)" or on lower level "((char*)ca + 5*sizeof(ca))" and
> > does not require any dereferencing.
> It does, since field offset macro takes the easy approach:
> #define FIELD_OFFSET(type, field) ((LONG)(INT_PTR)&(((type *)0)->field))
> which basically dereferences a null pointer to get the offset. This
> would be a bug in cppcheck since we don't actually dereference ca.
> Moreover, since cppcheck doesn't catch the similar FIELD_OFFSET uses
> as bugs, it seems that it is mistaking ca for the local ca, as
> opposed to the cs_t->ca.
I suspect that the above is technically illegal C.
Mainly because pointer arithmetic is only defined for pointers to
objects - and no object can have the address 0.
This is why offsetof() is defined as a builtin in more recent GCC.
The case in question tries to evaluate:
which does seem to contain a reference to beyond the end of the array!
Modern C allows the last entry of a struct to be ca (ie no array bound)
for these situations where a structure will be malloced with dynamic size.
There is, however, a fubar in the standard. offsetof() is defined to
return a compile-time constant - so the result can be used as an array
size etc. However there are times when you want to do:
and this now reported as illegal by gcc unless 'espression' is a compile
time constant :-(
David Laight: david at l8s.co.uk
More information about the wine-devel