Reputation: 19837
I've been reading around SO and have come across the following questions which touch on why typedefing pointer types is bad.
Opaque C structs: how should they be declared? and Const-correctness and immutable allocated objects
I was wondering if someone could expand and explain why typedefing pointer types is bad and perhaps provide some examples of where errors might occur.
Also, if typedefing pointer types is indeed a no-no, then why does the Win32 API do it? in Win32 HANDLE
(and effectively Handle types) are typedef'd as a void *
.
Upvotes: 4
Views: 579
Reputation: 70
Sometimes you need to forward-declare a structure pointer for a function declaration to compile. You can't just forward-declare the structure.
typedef struct my_struct * my_struct_ptr;
extern void my_func( my_struct_ptr pointer );
typedef struct _my_struct { int a_field; } my_struct;
(using st20cc 3.63)
Upvotes: 0
Reputation: 36082
By "typedefing" a pointer you effectively are following C practice and not C++ practice. In C in order to hide implementation details, a typedef is often used as it allows for a certain rudimentary form of data hiding:
typedef struct somestruct* pointer;
void foo(pointer p);
if later changed to
typedef struct someotherstruct* pointer;
void foo(pointer p);
you don't have to change all function parameters that use the pointer to "struct someotherstruct*" you can even fake polymorphism with this by adding new fields in someotherstruct.
In C++ there are other ways to achieve the above in a better way.
edit: maybe data hiding is a too strong word here but it allows you to change the implementation of the pointer that uses the pointer without breaking existing code (if done right)
Upvotes: 1
Reputation: 145269
Johannes has already remarked that typedef
'ing pointers is not inherently bad, and I agree.
Some guidelines, based on my subjective opinion of clarity & maintainability:
Generally do typedef
function pointer types.
Reason:
Function pointer declarations can get really messy & unreadable.
Generally don't typedef
raw object pointers where the pointer type is not an abstraction (e.g., when you just need a "pointer to T").
Reason 1:
It's more clear to see Foo*
or Foo const*
than, say, FooPtr
. With the name you have to look up the name to see what it's defined as. Perhaps it's some smart pointer, perhaps it's a pointer to const
, whatever; the name makes you needlessly look elsewhere.
Reason 2:
Some programmers are confused by the combination of const
and typedef
'ed pointer types. E.g. in Microsoft code I've seen the equivalent of FooPtr const
many times, where the programmer evidently thought it meant Foo const*
. But it doesn't, it means Foo* const
.
Generally do typedef
also a raw object pointer when the pointer type is an abstraction, a pointer type that conceivably can be replaced with some other type in the future, like e.g. HANDLE
.
Reason: The same as for using named constants: without a proper name a search and replace can change occurrences that mean something else, and can fail to change occurrences that are not expressed in the exact "right" way.
However, as with nearly all kinds of style, the arguments pro and con are pretty weak, and so the choice in the end boils down to personal preference, coding standards, co-workers' opinions, and so on.
Given a free choice the above is generally what I'd choose. But I have deviated from those guidelines/rules in special cases. As with good art, good code is produced by those who know the rules well enough to also know when to break 'em…
Cheers & hth.,
Upvotes: 11
Reputation: 100658
There's nothing wrong with using pointer typedefs but you need to keep in mind that typedefs do not define new types (like classes do) but define aliases for existing types. This means that if you have two typedefs which are aliases of the same type, you can't rely on C++'s type checking to prevent you from inadvertently mixing them up.
Upvotes: 0
Reputation: 283634
If you intend to provide a handle type at the public interface to your library, use a typedef. Do not expose it as struct foo*
. Whether a handle is a pointer or not is purely an implementation detail... it will always act as if it is a pointer, but it is often more convenient to use an index into some internal data structure.
Upvotes: 2
Reputation: 506955
It's not objectively bad to typedef pointer types. Much well written code uses it to typedef pointer to handler function types and it's also common for things like HANDLER
.
It may be one's personal opinion that it's bad, but it definitely isn't well-accepted opinion. I for one don't agree with that opinion at all. I myself use that option more seldom, but I still don't think it's "bad".
Upvotes: 6
Reputation: 37930
Both Windows and POSIX have typedef'ed pointers, but that doesn't mean it's always good practice. It's mostly to hide implementation details, but that's not always a good thing.
Upvotes: 1
Reputation: 23268
Well if it's not clear what is a pointer and what isn't you may have memory issues, windows typedefs HANDLE as void * because they provide methods for getting and cleaning up handles. It's not a bad thing to do but if many people are working on a project I would recommend against it. It's mostly a clarity issue.
Upvotes: 0