[comp.lang.c] typedef vs #define

em@cbnewsh.ATT.COM (edward.man) (02/24/90)

Is there any compiler writer out there? I have a C question that's
best answered by C compiler writers. Of course other C experts
can also provide insights and comments. However, I am looking for
a sure answer. The question is:

Consider the following two C statements:
	typedef short	FLAGS
	#define FLAGS	short

If I had two identical pieces of code, one used the "typedef" and
ther other "#define" as defined above, would there be any difference
in the compiled code? Does the C compiler handle the two differently?

I know "#define" is handled by cpp and the compiler never sees FLAGS.
How is "typedef" handled, by cpp or the compiler?

Ed Man
AT&T Bell Laboratories
att!hotlf!man

amull@Morgan.COM (Andrew P. Mullhaupt) (02/25/90)

In article <8430@cbnewsh.ATT.COM>, em@cbnewsh.ATT.COM (edward.man) writes:
> 
> Is there any compiler writer out there? I have a C question that's
> best answered by C compiler writers. Of course other C experts
> can also provide insights and comments. However, I am looking for
> a sure answer. 
(Then make sure to check the info you get from the net with the
new ANSI standard).
>	The question is:
> 
> Consider the following two C statements:
> 	typedef short	FLAGS
> 	#define FLAGS	short
> 
> If I had two identical pieces of code, one used the "typedef" and
> ther other "#define" as defined above, would there be any difference
> in the compiled code? Does the C compiler handle the two differently?

If your code compiles, it shouldn't result in different object code,
although debugging information could conceivably be different. However,
the exposure to name conflicts of the two approches differs. The lexical
scope of the typedef is one matter, but the #define can be modified by
the #undef directive. 

> 
> I know "#define" is handled by cpp and the compiler never sees FLAGS.
> How is "typedef" handled, by cpp or the compiler?

The preprocessor doesn't process the typedef.

The easiest way to find out the difference here is to consider an
example with pointer types. If you will turn to page 146 in K&R2
you will find the following:

"In effect, typedef is like #define, except that since it is
interpreted by the compiler, it can cope with textual substitutions
that are beyond the capabilities of the preprocessor. For example,

	typedef int (*PFI)(char *, char *);

creates the type PFI, for 'pointer to function (of two char *
arguments) returning int,' which can be used in contexts like

	PFI strcmp, numcmp;

in the sort of program of Chapter 5."

Later,
Andrew Mullhaupt

henry@utzoo.uucp (Henry Spencer) (02/25/90)

In article <8430@cbnewsh.ATT.COM> em@cbnewsh.ATT.COM (edward.man) writes:
>	typedef short	FLAGS
>	#define FLAGS	short
>
>If I had two identical pieces of code, one used the "typedef" and
>ther other "#define" as defined above, would there be any difference
>in the compiled code? Does the C compiler handle the two differently?

The #define is handled by the preprocessor, while the typedef is handled
by the compiler proper.  (Actually, a less implementation-dependent way
of stating this is that the #define is handled in ANSI C translation
phase 4 while typedef is handled in phase 7.)  In this particular case,
it will make little difference.  However, consider:

	typedef int (*intfp)();
	intfp ptrarray[10];

You can't do that with #define.
-- 
"The N in NFS stands for Not, |     Henry Spencer at U of Toronto Zoology
or Need, or perhaps Nightmare"| uunet!attcan!utzoo!henry henry@zoo.toronto.edu

nfs@notecnirp.Princeton.EDU (Norbert Schlenker) (02/26/90)

In article <752@s5.Morgan.COM> amull@Morgan.COM (Andrew P. Mullhaupt) writes:
>In article <8430@cbnewsh.ATT.COM>, em@cbnewsh.ATT.COM (edward.man) writes:
>> 
>>	The question is:
>> 
>> Consider the following two C statements:
>> 	typedef short	FLAGS
>> 	#define FLAGS	short
>> 
>> If I had two identical pieces of code, one used the "typedef" and
>> ther other "#define" as defined above, would there be any difference
>> in the compiled code? Does the C compiler handle the two differently?
>
>If your code compiles, it shouldn't result in different object code...

But beware.  If we change the question only slightly, to:

Consider the following two C statements:
 	typedef short * FLAGS
 	#define FLAGS short *
 
If I had two identical pieces of code, one used the "typedef" and
ther other "#define" as defined above, would there be any difference
in the compiled code? Does the C compiler handle the two differently?

Now there's a considerable difference between the two.  Imagine the
declaration:

FLAGS x, y;

The typedef results in (probably) what people expect, namely that both
x and y are pointers to short int.  The #define makes x a FLAGS and y
a short, probably not what you want.

bright@Data-IO.COM (Walter Bright) (02/27/90)

In article <8430@cbnewsh.ATT.COM> em@cbnewsh.ATT.COM (edward.man) writes:
<Consider the following two C statements:
<	typedef short	FLAGS;
<	#define FLAGS	short
<If I had two identical pieces of code, one used the "typedef" and
<ther other "#define" as defined above, would there be any difference
<in the compiled code? Does the C compiler handle the two differently?

There is *no* difference in semantics for declarations such as:
	FLAGS f;
	short *pf = &f;
	FLAGS *a[10];
However, there is a difference in:
	unsigned FLAGS f;	/* error if FLAGS is a typedef */
There are also subtle differences between:
	{	unsigned short; }	/* if FLAGS is a macro	*/
and:
	{	unsigned FLAGS;  }	/* if FLAGS is a typedef	*/
Also, a symbolic debugger would know about the typedef, but not
the macro.

I'd recommend using the typedef unless there is a very good reason not to.

schaut@cat9.cs.wisc.edu (Rick Schaut) (02/27/90)

In article <1990Feb24.234433.14252@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
| 
| The #define is handled by the preprocessor, while the typedef is handled
| by the compiler proper.  (Actually, a less implementation-dependent way
| of stating this is that the #define is handled in ANSI C translation
| phase 4 while typedef is handled in phase 7.)  In this particular case,
| it will make little difference.  However, consider:
| 
| 	typedef int (*intfp)();
| 	intfp ptrarray[10];

Good example, but for those who aren't too adept at parsing C type
declarations perhaps the following is a bit more clear:

	typedef int (*ptr_to_int_function)();
	ptr_to_int_function funct_ptr_array[NUMFUNCTS];
--
Rick (schaut@garfield.cs.wisc.edu)

"I'm a theory geek; we use Turing machines!"--Gary Lewandowski

amull@Morgan.COM (Andrew P. Mullhaupt) (02/28/90)

In article <24495@princeton.Princeton.EDU>, nfs@notecnirp.Princeton.EDU (Norbert Schlenker) writes:
! 
! But beware.  If we change the question only slightly, to:
! Consider the following two C statements:
!  	typedef short * FLAGS
!  	#define FLAGS short *
! 
! Now there's a considerable difference between the two.  Imagine the
! declaration:
! 
! FLAGS x, y;
! 
! The typedef results in (probably) what people expect, namely that both
! x and y are pointers to short int.  The #define makes x a FLAGS and y
! a short, probably not what you want.

I clearly pointed out this distinction in the quote I gave from K&R2
in my posting. Did only a fragment get all the way over the net?

Also: I am posting this because I can't get mail to you...

Later,
Andrew Mullhaupt