Path: utzoo!utgpu!news-server.csri.toronto.edu!mailrus!cs.utexas.edu!yale!mintaka!bloom-beacon!world!burley From: burley@world.std.com (James C Burley) Newsgroups: comp.lang.c Subject: Re: undefining a typedef Message-ID: Date: 11 Aug 90 06:58:50 GMT References: <1820006@hpsad.HP.COM> Sender: burley@world.std.com (James C Burley) Organization: The World Lines: 75 In-Reply-To: jose@hpsad.HP.COM's message of 10 Aug 90 16:07:33 GMT In article <1820006@hpsad.HP.COM> jose@hpsad.HP.COM (Jose Gomez-Rubio (SEED Student)) writes: How does one undefine a typedef construction in a header file? The problem is that a specific typedef construction is declared unconditionally in 3 separate header files in a source file that includes those 3 specific header files. I've tried #ifndef foobar ... #endif and #if !defined (foobar) ... #endif to no avail. The compiler still complains about redefinition of typedef and refuses to continue. The "#" directives like "#ifdef" and "#if defined" refer ONLY to whether macro names have been defined; they do not apply to other C names like types, enums, variable names, and the like. A typedef is NOT a macro, so it is not "defined" from the point of view of "#" directives. Further, I know of no way to undo a typedef in the same way one can undo a macro. A common solution is for any header file that wants to make use of a typedef for which it isn't solely responsible for defining to wrap the typedef in a macro-def-test-and-def sequence. All header files that need to make use (and hence possibly define) that typedef should do the same. For example, the ANSI C headers themselves might do something like: #ifndef _SIZE_T #define _SIZE_T typedef int size_t; #endif So the typedef for "size_t" happens only if no other header file including ALL FOUR of the above lines has been previously #included in the current compilation unit. But if you have more control of the project, and because where one wants to define a typedef, one typically wants to do so much more, I suggest you look into separating the typedef (and related declarations) into its own header file. That way, each header file that depends on the typedef (and other defs with it) can simply do #include "mydefs.h" Then the file "mydefs.h" looks like this: /* Comments... */ #ifndef MYDEFS_H #define MYDEFS_H ...declarations including, for example, "typedef struct foo *Foo;" #endif That is, the "useful" contents of the file mydefs.h actually gets processed only once per source file that includes it, no matter how many header files (included by the source file) include it. This is because the first time it gets processed, MYDEFS_H gets defined; after that, MYDEFS_H prevents the file from being processed. I've gotten to where I use canonical header file constructions that allow me to quickly and easily "plug in" what I need where I need it, and never have to worry about ordering dependencies for #include files (or easily fix them when I detect, for example, that one header file fails to include another on which it depends), even in cases where mutual interdependencies exist between header files. (For example, when one header file defines an object that points to an object defined by another header file, and that latter object also points to the former object.) On a large (100K-line) C project I used to work on, the ordering dependencies got frustrating and nearly insoluble at times, so I developed my system as a means of piece-by-piece improving that system, and I've used it from the beginning on my current (50K-line) project without any hiccups (yet). I won't bore you with the details or anything, because you should be able to develop such canonical header files for your own needs (and mine might not meet those). James Craig Burley, Software Craftsperson burley@world.std.com