Is It a Good Idea to Typedef Pointers

typedef with pointer in C [duplicate]

Short version:

typedef ListNode *ListNodePtr;

defines ListeNodePtr as a pointer to ListNode.

You may wonder why the asterisk is "sticking" to ListNodePtr here. That's because in C declarations, being a pointer is considered a type modifier, so in a declaration, it's part of the declarator (the identifier of the variable or typedef'd type).(*) This is relevant as soon as you have multiple declarations in a single line, e.g. the following:

int *a, b;

would define a pointer to int a and a plain int b.

You could write it as

int* a, b;

but that would be very confusing, because b would still not be a pointer.

All that being said, I personally consider it bad style to typedef a pointer, because as a C programmer, you know the meaning of an asterisk. Hiding it behind a typedef (and as done here, replacing it by some non-standard suffix like "Ptr") just makes the code harder to read for others.

(*) added footnote here: the reasoning behind this design is that declarations should look the same as usage. *a dereferences a pointer, so *a should as well declare a pointer.

Is it a good idea to typedef pointers?

This can be appropriate when the pointer itself can be regarded as a "black box", that is, a piece of data whose internal representation should be irrelevant to the code.

Essentially, if your code will never dereference the pointer, and you just pass it around API functions (sometimes by reference), then not only does the typedef reduce the number of *s in your code, but also suggests to the programmer that the pointer shouldn't really be meddled with.

This also makes it easier to change the API in the future if the need arises. For instance, if you change to using an ID rather than a pointer (or vice versa) existing code won't break because the pointer was never supposed to be dereferenced in the first place.

Is typedef'ing a pointer type considered bad practice? [duplicate]

In general, it's a bad practice. The significant problem is that it does not play well with const:

typedef type_t *TYPE;
extern void set_type(TYPE t);

void foo(const TYPE mytype) {
set_type(mytype); // Error expected, but in fact compiles
}

In order for the author of foo() to express what they really mean, the library that provides TYPE must also provide CONST_TYPE:

typedef const type_t *CONST_TYPE;

so that foo() can have the signature void foo(CONST_TYPE mytype), and at this point we have descended into farce.

Hence a rule of thumb:

Make typedefs of structs (particularly incomplete structs), not pointers to those structs.

If the definition of the underlying struct is not to be publicly available (which is often laudable), then that encapsulation should be supplied by the struct being incomplete, rather than by inconvenient typedefs:

struct type_t;
typedef struct type_t type_t;

void set_type(type_t *);
int get_type_field(const type_t *);

In C, is it good form to use typedef for a pointer?

I would use pointer typedefs only in situations when the pointer nature of the resultant type is of no significance. For example, pointer typedef is justified when one wants to declare an opaque "handle" type which just happens to be implemented as a pointer, but is not supposed to be usable as a pointer by the user.

typedef struct HashTableImpl *HashTable;
/* 'struct HashTableImpl' is (or is supposed to be) an opaque type */

In the above example, HashTable is a "handle" for a hash table. The user will receive that handle initially from, say, CreateHashTable function and pass it to, say, HashInsert function and such. The user is not supposed to care (or even know) that HashTable is a pointer.

But in cases when the user is supposed to understand that the type is actually a pointer and is usable as a pointer, pointer typedefs are significantly obfuscating the code. I would avoid them. Declaring pointers explicitly makes code more readable.

It is interesting to note that C standard library avoids such pointer typedefs. For example, FILE is obviously intended to be used as an opaque type, which means that the library could have defined it as typedef FILE <some pointer type> instead of making us to use FILE * all the time. But for some reason they decided not to.

Typedef function and is it useful? [duplicate]

You've declared fnr as a function type. While a function type cannot be assigned to, a pointer to a function type can. For example:

typedef void fnr(int x);

void f(int x)
{
printf("x=%d\n", x);
}

int main()
{
fnr *t = f;
t(1);
}

You could also define the typedef as a function pointer:

typedef void (*fnr)(int x);
...
fnr t = f;

Using a typedef for a function pointer is most useful when a function pointer is either passed to or returned from a function. As an example, let's look at the signal function which does both:

  typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

The second parameter to this function is a pointer to a signal handling function, and it also returns a pointer to a signal handling function. Without the typedef, it would look like this:

void (*signal(int signum, void (*handler)(int)))(int)

use pointer to struct or not when using typedef in C [duplicate]

I would require API users to type the "*", i.e. typedef the struct, not a pointer to the struct. This is the widely-used style in GLib, which is one of the more popular C stacks.

It works out well because it is important to know whether you have a pointer to a struct or the struct itself. For example, can you store NULL in a variable of the type? If you hide that an object is a pointer, you have to create a special NIL_NODE or other value to replace NULL. If you just make it a pointer, then people can treat it like one.

Another important benefit is the ability to put the actual struct definition somewhere private, i.e. in the .c file instead of in the header. You can put just the typedef in the header, while keeping the struct itself opaque to API users. This requires people to only use the exported methods that you provide to manipulate the struct. It also means you don't have to rebuild the world if you change the struct fields.

Yet another reason to take this path is that sometimes you do want a struct that can be copied, and you still want to typedef it. Take a thing like GdkPoint:

  typedef struct {
int x, y;
} GdkPoint;

Here it's useful to allow direct struct access, like:

 GdkPoint point = { 10, 10 };
GdkPoint copy = point;
do_stuff_with_point(©);

However, if your convention is that the "GdkPoint" typedef would be a pointer, you're going to have to be inconsistent.

Code is just clearer if you can tell what's a pointer and what isn't, and code is better encapsulated if you don't put struct definitions in the header (for structs that represent abstract, opaque data types, which is maybe the most common kind).

My default template for a C data type is something like this in the header:

typedef struct MyType MyType;
MyType* my_type_new(void);
void my_type_unref(MyType *t);
void my_type_ref(MyType *t);

Then the actual "struct MyType" in the .c file, along with the new, the unref, and any operations on the type.

The exception would be for types such as Point, Rectangle, Color where it's "plain old data" and direct field access is desired; another variation is to have a my_type_free() instead of _unref() if you don't need refcounting.

Anyhow, this is one style, basically the GLib style, that's widely-used and is known to work well.

Why should we typedef a struct so often in C?

As Greg Hewgill said, the typedef means you no longer have to write struct all over the place. That not only saves keystrokes, it also can make the code cleaner since it provides a smidgen more abstraction.

Stuff like

typedef struct {
int x, y;
} Point;

Point point_new(int x, int y)
{
Point a;
a.x = x;
a.y = y;
return a;
}

becomes cleaner when you don't need to see the "struct" keyword all over the place, it looks more as if there really is a type called "Point" in your language. Which, after the typedef, is the case I guess.

Also note that while your example (and mine) omitted naming the struct itself, actually naming it is also useful for when you want to provide an opaque type. Then you'd have code like this in the header, for instance:

typedef struct Point Point;

Point * point_new(int x, int y);

and then provide the struct definition in the implementation file:

struct Point
{
int x, y;
};

Point * point_new(int x, int y)
{
Point *p;
if((p = malloc(sizeof *p)) != NULL)
{
p->x = x;
p->y = y;
}
return p;
}

In this latter case, you cannot return the Point by value, since its definition is hidden from users of the header file. This is a technique used widely in GTK+, for instance.

UPDATE Note that there are also highly-regarded C projects where this use of typedef to hide struct is considered a bad idea, the Linux kernel is probably the most well-known such project. See Chapter 5 of The Linux Kernel CodingStyle document for Linus' angry words. :) My point is that the "should" in the question is perhaps not set in stone, after all.

C typedef of pointer to structure

Absolutely valid.
Usually, you can take full advantage of this way by defining two types together:

typedef struct
{
int a;
int b;
} S1, *S1PTR;

Where S1 is a struct and S1PTR is the pointer to this struct.



Related Topics



Leave a reply



Submit