[LCP]typedefs in .h

David Spencer David.W.Spencer at oracle.com
Thu Jan 24 01:26:41 UTC 2002


My own personal solution is temporarily to #define the thing you're
looking for to some definitely invalid code, then #include the header. 
When the compiler gets to the now *re*-definition of that symbol it
errors out when it expands the symbol and tries to parse the line.  The
bonus this approach has over find /usr/include -name \*.h -exec grep
FILE {} \; -print is that this greps all the headers and may come up
with duplicates, unused entries etc (and on my system returns 1646 lines
of stuff to search through), whereas with my approach the compiler is
parsing all the symbols and tracking through all the headers that you'll
*really* be using, so when it comes across the redefinition you can be
certain that's the correct one.

For example, looking for the definition of FILE:

err1.c:

#define FILE xyz + - yy^
#include <stdio.h>

It's worth bunging enough stuff in there to be definite because if we
just define FILE as seaside the following program compiles and links
fine:

dave at feathers:~/prog/c > gcc err2.c
dave at feathers:~/prog/c > cat err2.c
#define FILE seaside

#include <stdio.h>

int main()
{
  seaside *f1;
}

dave at feathers:~/prog/c > ls
a.out*
err2.c



gcc err1.c
In file included from err1.c:3:
/usr/include/stdio.h:44: parse error before `+'

...and about a million other (unsurprising) parse errors, because the
expansion of FILE makes no sense whatsoever.  Now go to stdio.h line 44
and what do you see but:

typedef struct _IO_FILE FILE;

Then it's just a matter of repeating the same trick for _IO_FILE,
assuming of course it isn't just in the same file, which on my system it
isn't.
Well, ok, by now you could just find /usr/include -name \*.h -exec grep
struct.\*_IO_FILE.\*\{ {} \; -print (probably, although this still risks
finding duplicates etc), but we may as well continue with the same
approach just to prove the concept.  Sure enough:

gcc err1.c (having changed FILE to _IO_FILE):

In file included from /usr/include/stdio.h:64,
                 from err1.c:3:
/usr/include/libio.h:158: parse error before `+'

and libio.h:158 is "struct _IO_jump_t;  struct _IO_FILE;"

and the full struct _IO_FILE is found in that same file on line 259.

Dave.


"Alton, Matthew" wrote:
> 
> This is an interesting problem.  We would often like to
> format data into printf()s for debugging output and
> sundry other purposes.  Alas, other than the GNU typeof()
> operator, I know of no decent method.  The problem
> really gets nasty in pthreads-land where a pthread_t can
> be absolutely anything from a short int to a void pointer
> to a kernel struct.  Associate each pthread_t with it's
> unique memory address, you say?  Fine, what's the real
> type of an addr_t?  We're full circle.
> 
> I would be very interested in any suggestions for
> overcoming this problem.
-- 
David Spencer
www.curlypi.com



More information about the linuxCprogramming mailing list