Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When don't I need a typedef?

Tags:

c++

c

typedef

I encountered some code reading

typedef enum eEnum { c1, c2 } tagEnum;

typedef struct { int i; double d; } tagMyStruct;

I heard rumours that these constructs date from C. In C++ you can easily write

enum eEnum { c1, c2 };
struct MyStruct { int i; double d; };

Is that true? When do you need the first variant?

like image 741
xtofl Avatar asked Feb 05 '09 15:02

xtofl


People also ask

When should you use typedef?

The typedef keyword allows the programmer to create new names for types such as int or, more commonly in C++, templated types--it literally stands for "type definition". Typedefs can be used both to provide more clarity to your code and to make it easier to make changes to the underlying data types that you use.

Does struct need typedef?

Basically struct is used to define a structure. But when we want to use it we have to use the struct keyword in C. If we use the typedef keyword, then a new name, we can use the struct by that name, without writing the struct keyword.

Is typedef necessary in C++?

typedef is necessary for many template metaprogramming tasks -- whenever a class is treated as a "compile-time type function", a typedef is used as a "compile-time type value" to obtain the resulting type.

Should I typedef structs in C?

typedef'ing structs is one of the greatest abuses of C, and has no place in well-written code. typedef is useful for de-obfuscating convoluted function pointer types and really serves no other useful purpose.


3 Answers

First, both declarations are legal in both C and C++. However, in C, they have slightly different semantics. (In particular, the way you refer to the struct later varies).

The key concept to understand is that in C, structs exist in a separate namespace. All built-in types, as well as typedefs exist in the "default" namespace. That is, when I type int, the compiler only checks this "default" namespace. If I type "tagMyStruct" as in your example, the compiler also only checks this one namespace. But depending which type of declaration you use, the struct may not exist in that namespace.

Structs are different, and exist in a separate namespace. So if I make the following declaration:

struct mystruct {};

I can not simply refer to it as mystruct. Instead, I have to specify that I want the mystruct which exists in the struct namespace:

void foo(struct mystruct bar); // Declare a function which takes a mystruct as its parameter

Which gets a bit verbose and awkward in the long run. Instead, you can typedef it into the default namespace:

typedef struct mystruct mystruct; // From now on, 'mystruct' in the normal namespace is an alias for 'mystruct' in the struct namespace

and now, my function can be declared in the straightforward way:

void foo(mystruct bar);

So your first example simply merges these two steps together: Declare a struct, and put an alias into the regular namespace. And of course, since we're typedeffing it anyway, we don't need the "original" name, so we can make the struct anonymous. So after your declaration

typedef struct { int i; double d; } tagMyStruct;

we have a struct with no name, which has been typedef'ed to 'tagMyStruct' in the default namespace.

That's how C treats it. Both types of declarations are valid, but one does not create the alias in the "default" namespace, so you have to use the struct keyword every time you refer to the type.

In C++, the separate struct namespace doesn't exist, so they mean the same thing. (but the shorter version is preferred).

Edit Just to be clear, no, C does not have namespaces. Not in the usual sense. C simply places identifiers into one of two predefined namespaces. The names of structs (and enums, as I recall) are placed in one, and all other identifiers in another. Technically, these are namespaces because they are separate "containers" in which names are placed to avoid conflicts, but they are certainly not namespaces in the C++/C# sense.

like image 84
jalf Avatar answered Oct 07 '22 10:10

jalf


In C, if you were to write

struct MyStruct { int i; double d; };

whenever you wanted to reference that type, you'd have to specify that you were talking about a struct:

struct MyStruct instanceOfMyStruct;
struct MyStruct *ptrToMyStruct;

With the typedef version:

typedef struct { int i; double d; } tagMyStruct;

you only have to write:

tagMyStruct instanceOfMyStruct;
tagMyStruct *ptrToMyStruct;

The other big advantage with the typedef'd version is that you can refer to the struct the same way in both C and C++, whereas in the second version they are refered to differently in C than in C++.

like image 37
Eclipse Avatar answered Oct 07 '22 09:10

Eclipse


It's just shorthand.

In the second instance, to declare the struct you'd do so with:

struct MyStruct a;

In the first variant, you'd do so with:

tagMyStruct a;
like image 38
Philip Reynolds Avatar answered Oct 07 '22 10:10

Philip Reynolds