#define and typedef

Jun 20, 2009 at 1:29am
closed account (S6k9GNh0)
As I've come to realize, I find the two more often than usual lately:

1
2
3
#define BOB BOB_struct

typedef BOB_struct BOB;


This performs the exact same to a point. #define simply replaces the context of BOB with BOB_struct and typedef creates a new type which says BOB is BOB_struct. My question now is what is more efficient. If I had the choice of using a defined macro should I use it? Is there harm in using the typedef? My assumption is that a typedef creates a syntax synonym and the compiler excepts it as the equivalent syntax as what the typedef declared. But I have no clue what it actually does so is there any real loss in using it?
Last edited on Jun 20, 2009 at 1:29am
Jun 20, 2009 at 1:37am
The typedef gives information to the compiler about how to interpret an identifier. It produces no code. The typedef is preferable to the macro because it's typed, and thus, less error prone.
Jun 20, 2009 at 1:44am
Neither is more efficient, as they'll both produce the same binary.

That said... typedef is more prefereable in my book. Avoid #define unless it's your only option.

#defines are done by the preprocessor which is oblivious to the program's context. This leads to obscure compiler errors when used improperly (the compiler error will say something that is not reflected by the code it's referring to at all -- you need to look up and expand the macro to know wtf it's talking about). They also don't work well with debuggers.

#define can also lead to other unexpected errors. What happens if there's a function or local variable in your program which also happens to be named BOB? #define doesn't care, it'll replace it anyway. It also doesn't care about namespace or scope -- a #define anywhere in the program can pollute any and all namespaces/functions/classes. This is a common problem with <windows.h> which #defines its own min/max macros -- which effectively screws you if you try to use std::numeric_limits<type>::max() or the like. You have to explicitly #undef them to avoid those errors.

typedefs are type aware and flow with C++ more naturally, rather than #defines which sort of force their way in.

edit: blargg @ helios quick response ;P at least we're in agreement.
Last edited on Jun 20, 2009 at 1:48am
Jun 20, 2009 at 1:54am
closed account (S6k9GNh0)
Thanks for the reply. I've been told that #define is most useful in functions since you can define a type with a function (I'm not discussing constants). Anyways, I appreciate the feedback and clearing yet another cloud.

I do have another question though. You can define a struct like so:
1
2
3
4
5
typedef struct
{
   int x;
   int y;
} bob;


What is the actual advantage of this method? Doesn't do the same as declaring a struct with a default name? I see this a LOT in almost every C based library I can find.
Last edited on Jun 20, 2009 at 1:57am
Jun 20, 2009 at 2:04am
In C, it didn't create an automatic typedef so you couldn't simply say, create a struct bob and then create instances of it using just bob, you had to use struct bob. The typedef struct way makes it so you can.
Jun 20, 2009 at 2:06am
A quick Googling of "typedef struct vs struct" reveals that, in C, using that syntax lets you refer to struct bob as just bob.
Jun 20, 2009 at 2:55am
[off-topic]
I knew a guy named Bob who hated his name for the very reasons illustrated in this thread...
Jun 20, 2009 at 3:16am
closed account (S6k9GNh0)
LOL! Ask if he's simple like his name. :D
Jun 20, 2009 at 2:42pm
I agree that typedef is preferable to #define only in that C++ programmers tend to strongly dislike macros, which is one of the main purposes of using #define. Although in the case, I hardly call the usage of #define as creating a macro; it is simply creating a more readable name for a type.

Unfortunately for the purposes of creating a new name for an existing type, both #define and typedef suck. The reason is because neither creates a strong type. For example:

1
2
3
4
5
6
7
8
9
10
typedef int Fruit;
typedef int Vegetable;

static const int Apple = 1;
static const int Banana = 2;

static const int Corn = 1;
static const int Peas = 2;

Vegetable favorite_veg = Apple;  // (!) Works just fine! 

Jun 20, 2009 at 3:07pm
But isn't that what enums are for?

1
2
3
4
enum Fruit { Apple, Banana };
enum Vegetable { Corn, Peas };

Vegetable favorite_veg = Apple;  // error 


I actually kind of prefer that typedef doesn't make a strong type. At least in some situations. I agree, though, that it might not be preferable sometimes. Perhaps there should be a modifier for it, like explicit typedef etc to make it a strong type.

But whatever, it is what it is.
Jun 20, 2009 at 5:23pm
But what if you want to assign a uint32_t to a ulong? The two types are compatible, so why should the compiler complain if the typedefs are different?
Topic archived. No new replies allowed.