[comp.lang.c] undefining a typedef

jose@hpsad.HP.COM (Jose Gomez-Rubio (SEED Student)) (08/10/90)

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.

In the interim, I've commented out the typedef's but I think there is
a better solution.

Thanks for the help!
--
jose@hpsad.hp.com

burley@world.std.com (James C Burley) (08/11/90)

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

browns@astro.pc.ab.com (Stan Brown, Oak Road Systems) (08/12/90)

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. 

I don't have a good solution, but I can help explain the problem.  #ifdef and
#if defined()--which is really the same thing--ask whether PREPROCESSOR symbols
are defined; i.e. whether the symbols have been #defined.  A typedef is not a
preprocessor symbol.

What I do in these cases is something like this:
   #ifndef TYPE_MUMBLE_DEFINED
   typedef char *MUMBLE[ ];
   #define TYPE_MUMBLE_DEFINED 1
   #endif
It's ugly, and I'd love to hear a better way.

Stan Brown, Oak Road Systems, (216) 371-0043
The opinions expressed are mine. Mine alone!  Nobody else is responsible for
them or even endorses them--except my cat Dexter, and he signed the power of
attorney only under my threat to cut off his Cat Chow!

kdq@demott.COM (Kevin D. Quitt) (08/12/90)

try:

#ifndef	__MYTYPE_DEFINED__
#define	__MYTYPE_DEFINED__

typedef ....


#endif


    Put this in each of your header files.

-- 
 _
Kevin D. Quitt         demott!kdq   kdq@demott.com
DeMott Electronics Co. 14707 Keswick St.   Van Nuys, CA 91405-1266
VOICE (818) 988-4975   FAX (818) 997-1190  MODEM (818) 997-4496 PEP last

                96.37% of all statistics are made up.

henry@zoo.toronto.edu (Henry Spencer) (08/12/90)

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?

You don't.  Typedef is not undoable.  For this reason, typedefs have to
be much more carefully coordinated than macros.
-- 
It is not possible to both understand  | Henry Spencer at U of Toronto Zoology
and appreciate Intel CPUs. -D.Wolfskill|  henry@zoo.toronto.edu   utzoo!henry

darcy@druid.uucp (D'Arcy J.M. Cain) (08/12/90)

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.
>

Bracket the typedef in each file as follows

#ifndef __FOO__
#define __FOO__
typedef int foo;
#endif


-- 
D'Arcy J.M. Cain (darcy@druid)     |
D'Arcy Cain Consulting             |   MS-DOS:  The Andrew Dice Clay
West Hill, Ontario, Canada         |   of operating systems.
+ 416 281 6094                     |

amull@Morgan.COM (Andrew P. Mullhaupt) (08/13/90)

In article <1990Aug11.230818.2782@zoo.toronto.edu>, henry@zoo.toronto.edu (Henry Spencer) writes:
> ...  Typedef is not undoable.  For this reason, typedefs have to
> be much more carefully coordinated than macros.

Speaking of typedefs and macros -- is there any way to get the
functionality of the GNU C extension "typeof" in ANSI or UNIX
style C? I would settle for being able to declare a variable x
as having the same type as variable y where, due to the fact that
the code is machine generated, it isn't simple to say what type
that variable y has.

Later,
Andrew Mullhaupt

henry@zoo.toronto.edu (Henry Spencer) (08/14/90)

In article <1460@s8.Morgan.COM> amull@Morgan.COM (Andrew P. Mullhaupt) writes:
>Speaking of typedefs and macros -- is there any way to get the
>functionality of the GNU C extension "typeof" in ANSI or UNIX
>style C? ...

No.
-- 
It is not possible to both understand  | Henry Spencer at U of Toronto Zoology
and appreciate Intel CPUs. -D.Wolfskill|  henry@zoo.toronto.edu   utzoo!henry