Regarding typedef and macro

S

sam_cit

I noticed that what is being done by typedef can very much be done by
macro, and i also think there must be a specific reason as to why
typedef was introduced,
what is the exact difference, and are there any reasons that we should
prefer one over the other and how is typedef internally implemented?
 
R

Richard Heathfield

(e-mail address removed) said:
I noticed that what is being done by typedef can very much be done by
macro, and i also think there must be a specific reason as to why
typedef was introduced,
what is the exact difference, and are there any reasons that we should
prefer one over the other and how is typedef internally implemented?

The exact difference is that typedef creates a synonym for an existing type,
whereas macros cause pp-token substitution to occur.

You should prefer typedef when you want a synonym for an existing type, but
you should prefer macros when you want pp-token substitution to occur.

The internal implementation of typedef is up to the implementor. There Is
More Than One Way To Do It.
 
R

Richard Bos

I noticed that what is being done by typedef can very much be done by
macro, and i also think there must be a specific reason as to why
typedef was introduced,
what is the exact difference, and are there any reasons that we should
prefer one over the other and how is typedef internally implemented?

A typedef is a proper type. A macro is a text substitution. There may
not seem to be much difference between typedef int number and #define
number int, but you try this:

#define pointer1 int *
typedef int * pointer2;

pointer1 a, b;
pointer2 c, d;

How many pointers?

Richard
 
B

Barry Schwarz

I noticed that what is being done by typedef can very much be done by
macro, and i also think there must be a specific reason as to why

Convert
typedef struct s1{
int m1;
struct s1 *m2;
} t1;
to a macro and then try to define two structure objects.
typedef was introduced,
what is the exact difference, and are there any reasons that we should
prefer one over the other and how is typedef internally implemented?


Remove del for email
 
E

Eric Sosman

I noticed that what is being done by typedef can very much be done by
macro, and i also think there must be a specific reason as to why
typedef was introduced,
what is the exact difference, and are there any reasons that we should
prefer one over the other and how is typedef internally implemented?

The canonical example of non-equivalence looks like

typedef char *CharPtr;
CharPtr p1, p2;

#define CHARPTR char *
CHARPTR q1, q2;

Once you've studied that one for a while, try this
challenge:

typedef double Matrix[4][4];
Matrix m1, m2;

#define MATRIX /* supply macro definition */
MATRIX x1, x2;

.... where your task is to provide a definition of MATRIX
that makes x1,x2 have the same type as m1,m2. (It is, of
course, considered cheating to use a typedef'ed name in
the expansion of MATRIX; the point of the exercise is to
discover something typedef can do easily that is difficult
to handle with unaided macro substitution.)

However, typedef is not all-powerful. Consider

#include <limits.h>
#if INT_MAX >= 1000000
typedef int Million;
#else
typedef long Million;
#endif
Million s1;
unsigned Million u1; /* illegal! */

#if INT_MAX >= 1000000
#define MILLION int
#else
#define MILLION long
#endif
MILLION s2;
unsigned MILLION u2; /* legal (albeit dumb) */
 
K

Kenneth Brody

I noticed that what is being done by typedef can very much be done by
macro, and i also think there must be a specific reason as to why
typedef was introduced,
what is the exact difference, and are there any reasons that we should
prefer one over the other and how is typedef internally implemented?

Perhaps the easiest way to think of this is to consider pointers,
and the difference between:

typedef char *CharPointer;
and
#define CharPointer char *

Specifically in the case of:

CharPointer pt1, pt2;

Also, type checking can be better enforced with typedefs than with
#defines. If you #define a new "type", the comipler has no way of
knowing the difference between your "type" and the base type. But,
with typedefs, your new type is treated as a distinct type. For
example:

typedef long MyLong;

The compiler can treat "MyLong" and "long" as two distinct types,
whereas in this case:

#define MyLong long

there is no distinction possible.

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
E

Eric Sosman

Kenneth said:
[...]
Also, type checking can be better enforced with typedefs than with
#defines. If you #define a new "type", the comipler has no way of
knowing the difference between your "type" and the base type. But,
with typedefs, your new type is treated as a distinct type. For
example:

typedef long MyLong;

The compiler can treat "MyLong" and "long" as two distinct types,
[...]

Since MyLong and long are the *same* type, a compiler that
gives them different "effective" treatment is broken. A compiler
or lint-like utility might issue warning messages -- a compiler
can issue warning messages about the phase of the moon -- but
a program using a MyLong in some context must have exactly the
same behavior as if a long were used instead.
 
K

Kenneth Brody

Eric said:
Kenneth said:
[...]
Also, type checking can be better enforced with typedefs than with
#defines. If you #define a new "type", the comipler has no way of
knowing the difference between your "type" and the base type. But,
with typedefs, your new type is treated as a distinct type. For
example:

typedef long MyLong;

The compiler can treat "MyLong" and "long" as two distinct types,
[...]

Since MyLong and long are the *same* type, a compiler that
gives them different "effective" treatment is broken. A compiler
or lint-like utility might issue warning messages -- a compiler
can issue warning messages about the phase of the moon -- but
a program using a MyLong in some context must have exactly the
same behavior as if a long were used instead.

Okay, I stand corrected.

What I _meant_ to say was that, for the purposes of type checking,
it can issue a warning if a prototype specifies MyLong as the type,
but you pass long (or anything else typedef'ed to long) instead,
as "MyLong" and "long" are distinct as far as type checking is
concerned.

Did I get it right this time?

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
K

Keith Thompson

Eric Sosman said:
However, typedef is not all-powerful. Consider

#include <limits.h>
#if INT_MAX >= 1000000
typedef int Million;
#else
typedef long Million;
#endif
Million s1;
unsigned Million u1; /* illegal! */

#if INT_MAX >= 1000000
#define MILLION int
#else
#define MILLION long
#endif
MILLION s2;
unsigned MILLION u2; /* legal (albeit dumb) */

Yup. But if I really wanted to do something like that, I'd write it
this way:

#include <limits.h>
#if INT_MAX >= 1000000
typedef int Million;
typedef unsigned int Unsigned_Million;
#else
typedef long Million;
typedef unsigned long Unsigned_Million;
#endif
Million s1;
Unsigned_Million u1;
 
K

Keith Thompson

Kenneth Brody said:
Eric said:
Kenneth said:
[...]
Also, type checking can be better enforced with typedefs than with
#defines. If you #define a new "type", the comipler has no way of
knowing the difference between your "type" and the base type. But,
with typedefs, your new type is treated as a distinct type. For
example:

typedef long MyLong;

The compiler can treat "MyLong" and "long" as two distinct types,
[...]

Since MyLong and long are the *same* type, a compiler that
gives them different "effective" treatment is broken. A compiler
or lint-like utility might issue warning messages -- a compiler
can issue warning messages about the phase of the moon -- but
a program using a MyLong in some context must have exactly the
same behavior as if a long were used instead.

Okay, I stand corrected.

What I _meant_ to say was that, for the purposes of type checking,
it can issue a warning if a prototype specifies MyLong as the type,
but you pass long (or anything else typedef'ed to long) instead,
as "MyLong" and "long" are distinct as far as type checking is
concerned.

Did I get it right this time?

Yes, but I'd be (mildly) surprised if a compiler actually issued such
a warning.

Typedefs really don't create new types; they just create new names for
existing types.
 
E

Eric Sosman

Kenneth said:
Eric said:
Kenneth said:
[...]
Also, type checking can be better enforced with typedefs than with
#defines. If you #define a new "type", the comipler has no way of
knowing the difference between your "type" and the base type. But,
with typedefs, your new type is treated as a distinct type. For
example:

typedef long MyLong;

The compiler can treat "MyLong" and "long" as two distinct types,
[...]
Since MyLong and long are the *same* type, a compiler that
gives them different "effective" treatment is broken. A compiler
or lint-like utility might issue warning messages -- a compiler
can issue warning messages about the phase of the moon -- but
a program using a MyLong in some context must have exactly the
same behavior as if a long were used instead.

Okay, I stand corrected.

What I _meant_ to say was that, for the purposes of type checking,
it can issue a warning if a prototype specifies MyLong as the type,
but you pass long (or anything else typedef'ed to long) instead,
as "MyLong" and "long" are distinct as far as type checking is
concerned.

Did I get it right this time?

As far as I can tell, yes. But any such warning falls under
the general heading of "compiler's discretion:" it can warn about
the phase of the moon, the lack or oversufficiency of comments,
your indenting style, or even spellnig errors in your identifiers.
It can warn and warn all day long, but (barring actual errors) it
must accept the program anyhow -- and if MyLong and YourLong are
typedef'ed aliases for long, they are interchangeable.
 
K

Kenneth Brody

Eric said:
Kenneth Brody wrote: [...]
Okay, I stand corrected.

What I _meant_ to say was that, for the purposes of type checking,
it can issue a warning if a prototype specifies MyLong as the type,
but you pass long (or anything else typedef'ed to long) instead,
as "MyLong" and "long" are distinct as far as type checking is
concerned.

Did I get it right this time?

As far as I can tell, yes. But any such warning falls under
the general heading of "compiler's discretion:" it can warn about
the phase of the moon, the lack or oversufficiency of comments,
your indenting style, or even spellnig errors in your identifiers.
It can warn and warn all day long, but (barring actual errors) it
must accept the program anyhow -- and if MyLong and YourLong are
typedef'ed aliases for long, they are interchangeable.

Isn't it nice how one can program in C for over 20 years and still
have some misconceptions, probably learned long ago and never
unlearned?

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
R

Random832

2006-12-15 said:
Eric said:
Kenneth Brody wrote: [...]
Okay, I stand corrected.

What I _meant_ to say was that, for the purposes of type checking,
it can issue a warning if a prototype specifies MyLong as the type,
but you pass long (or anything else typedef'ed to long) instead,
as "MyLong" and "long" are distinct as far as type checking is
concerned.

Did I get it right this time?

As far as I can tell, yes. But any such warning falls under
the general heading of "compiler's discretion:" it can warn about
the phase of the moon, the lack or oversufficiency of comments,
your indenting style, or even spellnig errors in your identifiers.
It can warn and warn all day long, but (barring actual errors) it
must accept the program anyhow -- and if MyLong and YourLong are
typedef'ed aliases for long, they are interchangeable.

Isn't it nice how one can program in C for over 20 years and still
have some misconceptions, probably learned long ago and never
unlearned?

Can you provide a standard cite for your claim that this is not the
case?
 
E

Eric Sosman

Kenneth said:
Eric said:
Kenneth Brody wrote: [...]
Okay, I stand corrected.

What I _meant_ to say was that, for the purposes of type checking,
it can issue a warning if a prototype specifies MyLong as the type,
but you pass long (or anything else typedef'ed to long) instead,
as "MyLong" and "long" are distinct as far as type checking is
concerned.

Did I get it right this time?
As far as I can tell, yes. But any such warning falls under
the general heading of "compiler's discretion:" it can warn about
the phase of the moon, the lack or oversufficiency of comments,
your indenting style, or even spellnig errors in your identifiers.
It can warn and warn all day long, but (barring actual errors) it
must accept the program anyhow -- and if MyLong and YourLong are
typedef'ed aliases for long, they are interchangeable.

Isn't it nice how one can program in C for over 20 years and still
have some misconceptions, probably learned long ago and never
unlearned?

I have fifty percent more misconceptions than you do.
Nyahh-nya-nyahh-nya-nyahh-nyaah!

(Or, as Mark Twain almost said, one lifetime is not
enough to master the C language.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top