|  | Typedef question |  | |
| | | mdh |  |
| Posted: Tue Sep 02, 2008 6:25 pm Post subject: Typedef question |  |
A quick ? question about Typedefs. There is a very brief discussion about this in K&R ( p146). Googling this group, there is a surprising dearth of questions about these. From one of the threads, there is sound advice ( to me at any rate) not to hide pointers behind typedefs. So, may I ask the group when the use of typedefs really makes sense?
Sorry if this is somewhat general, but there are no exercises ( not that I am asking for any!!) provided. |
| |
| | | Eric Sosman |  |
| Posted: Tue Sep 02, 2008 6:26 pm Post subject: Re: Typedef question |  |
| |  | |
mdh wrote:
| Quote: | A quick ? question about Typedefs. There is a very brief discussion about this in K&R ( p146). Googling this group, there is a surprising dearth of questions about these. From one of the threads, there is sound advice ( to me at any rate) not to hide pointers behind typedefs. So, may I ask the group when the use of typedefs really makes sense?
|
One important use for typedef is to deal with the variability of C's native types from machine to machine. For example, Park and Miller's "Minimal Standard Random Number Generator" uses numbers as large as 2147483646. Many machines' int type will suffice for this magnitude, but on some you may need to resort to long. You could just use long everywhere in the code, but on some machines that may be overkill. Here's a possible solution:
#include <limits.h> #if INT_MAX >= 2147483646 typedef int MSint; /* int is enough */ #else typedef long MSint; /* int too small; use long */ #endif
.... and then write the code using MSint throughout. The typedef encapsulates your choice of the appropriate native type to use in the environment at hand. It doesn't solve every problem -- for example, if you use printf() or scanf() with these numbers, you need to choose the right format strings -- but it can smooth out a good many machine-to-machine differences.
Another important use is to improve readability by decomposing complicated declarations into manageable pieces. The classic example of this is the declaration of the signal() function:
void (*signal(int sig, void (*func)(int)))(int);
Most people will find the code more readable if a typedef is used (there's more than one way to do this):
typedef void (SigHandler)(int sig); SigHandler *signal(int sig, SigHandler *func);
Another use is to attach suggestive one-word names to struct and union types, as in
typedef struct hashItem { unsigned int hashValue; const void *itemPointer; struct hashItem *nextItem; } HashItem;
People differ about whether this is a good idea or not. Some feel that the struct-ness of the thing cannot be hidden (you're going to use . and -> with it, after all), so the attempt to hide it is feeble and maybe even obfuscatory. Others feel that it's quicker and easier to write and read `HashItem' than `struct hashItem', and that using the shorter phrase improves readability. I'm in the latter camp (especially when the nature of the struct or union is private to a library and only a `HashItem*' is exported to the clients), but my preference isn't so strong that I'd take up arms against the unbelievers. You'll have to consult your own tastes on this one.
Finally, the pointer thing. Even when a library traffics in pointers to private structs, the fact that they're pointers is usually something the caller must know, if for no other reason than to test a returned value against NULL. For this reason, I'd prefer to say that a function returns a `HashItem*' than a `HashItemPointer'; the latter just makes it harder to discern what you're dealing with. (Is this stance inconsistent with my preference for `HashItem' over `struct hashItem'? Probably, but as I said earlier I'm not going to war over it.)
-- Eric.Sosman@sun.com |
| |
| | | Guest |  |
| Posted: Tue Sep 02, 2008 7:50 pm Post subject: Re: Typedef question |  |
| |  | |
mdh wrote:
| Quote: | A quick ? question about Typedefs. There is a very brief discussion about this in K&R ( p146). Googling this group, there is a surprising dearth of questions about these. From one of the threads, there is sound advice ( to me at any rate) not to hide pointers behind typedefs. So, may I ask the group when the use of typedefs really makes sense?
Sorry if this is somewhat general, but there are no exercises ( not that I am asking for any!!) provided.
|
Typedefs serve at least two main purposes. The most common one is to allow you to write code that uses a particular type, when you anticipate that the type it should use might be different in different contexts. A simple example is size_t, which is a typedef set up by the C standard library itself. It might be 'unsigned char' on one implementation, and "unsigned long long" on another. However, you don't have to make any changes to your code when moving it from one implementation to the other, because the change occurs inside the C standard headers that typedef size_t..
The second use I've seen is for simplifying type declarations. If you make a lot of use of unsigned char, it's convenient to use
typedef unsigned char uchar;
Similarly, it's convenient to use
typedef struct { int i; double d; } intdouble;
rather than
struct intdouble { int i; double d;};
mainly because it allows you to refer to the type using "intdouble" rather than "struct intdouble". This is especially attractive to people who are used to C++, where the keyword struct would be needed only in the definition of the type, and not when using it.
And, as you've already seen, typedef can be used to simplify code that relies upon function pointers. |
| |
| | | mdh |  |
| Posted: Tue Sep 02, 2008 8:22 pm Post subject: Re: Typedef question |  |
On Sep 2, 12:47 pm, Eric Sosman <Eric.Sos...@sun.com> wrote:
| Quote: | mdh wrote: A quick ? question about Typedefs.
One important use for typedef is to deal with the variability of C's native types from machine to machine. Another important use is to improve readability by decomposing complicated declarations into manageable pieces.
Eric.Sos...@sun.com
|
thank you Eric for that explanation. |
| |
| | | mdh |  |
| Posted: Tue Sep 02, 2008 8:23 pm Post subject: Re: Typedef question |  |
On Sep 2, 12:50 pm, jameskuy...@verizon.net wrote:
| Quote: | mdh wrote: A quick ? question about Typedefs.
Typedefs serve at least two main purposes. The most common one is to allow you to write code that uses a particular type.
The second use I've seen is for simplifying type declarations. If you make a lot of use of unsigned char, it's convenient to use
|
thank you James. Appreciated. |
| |
| | | Guest |  |
| Posted: Tue Sep 02, 2008 9:23 pm Post subject: Re: Typedef question |  |
| |  | |
On Sep 2, 10:50 pm, jameskuy...@verizon.net wrote:
| Quote: | mdh wrote: A quick ? question about Typedefs. There is a very brief discussion about this in K&R ( p146). Googling this group, there is a surprising dearth of questions about these. From one of the threads, there is sound advice ( to me at any rate) not to hide pointers behind typedefs. So, may I ask the group when the use of typedefs really makes sense?
Sorry if this is somewhat general, but there are no exercises ( not that I am asking for any!!) provided.
Typedefs serve at least two main purposes. The most common one is to allow you to write code that uses a particular type, when you anticipate that the type it should use might be different in different contexts. A simple example is size_t, which is a typedef set up by the C standard library itself. It might be 'unsigned char' on one implementation, and "unsigned long long" on another. However, you don't have to make any changes to your code when moving it from one implementation to the other, because the change occurs inside the C standard headers that typedef size_t..
The second use I've seen is for simplifying type declarations. If you make a lot of use of unsigned char, it's convenient to use
typedef unsigned char uchar;
|
Ugh. I don't really like code that does that. Also code that has u8, uchar8 etc. IMHO typedef is not there to save you typing. You could edit your editor so whenever you type `uchar ' it replaces it with unsigned char. |
| |
| | | pete |  |
| Posted: Tue Sep 02, 2008 9:24 pm Post subject: Re: Typedef question |  |
| |  | |
vippstar@gmail.com wrote:
| Quote: | On Sep 2, 10:50 pm, jameskuy...@verizon.net wrote: mdh wrote: A quick ? question about Typedefs. There is a very brief discussion about this in K&R ( p146). Googling this group, there is a surprising dearth of questions about these. From one of the threads, there is sound advice ( to me at any rate) not to hide pointers behind typedefs. So, may I ask the group when the use of typedefs really makes sense? Sorry if this is somewhat general, but there are no exercises ( not that I am asking for any!!) provided. Typedefs serve at least two main purposes. The most common one is to allow you to write code that uses a particular type, when you anticipate that the type it should use might be different in different contexts. A simple example is size_t, which is a typedef set up by the C standard library itself. It might be 'unsigned char' on one implementation, and "unsigned long long" on another. However, you don't have to make any changes to your code when moving it from one implementation to the other, because the change occurs inside the C standard headers that typedef size_t..
The second use I've seen is for simplifying type declarations. If you make a lot of use of unsigned char, it's convenient to use
typedef unsigned char uchar;
Ugh. I don't really like code that does that.
|
Me neither. It's just one more thing that needs to be looked up in order to read the code.
-- pete |
| |
| | | Keith Thompson |  |
| Posted: Tue Sep 02, 2008 9:55 pm Post subject: Re: Typedef question |  |
| |  | |
mdh <mdeh@comcast.net> writes:
| Quote: | A quick ? question about Typedefs. There is a very brief discussion about this in K&R ( p146). Googling this group, there is a surprising dearth of questions about these. From one of the threads, there is sound advice ( to me at any rate) not to hide pointers behind typedefs. So, may I ask the group when the use of typedefs really makes sense?
Sorry if this is somewhat general, but there are no exercises ( not that I am asking for any!!) provided.
|
A typedef creates an alias (a name consisting of a single identifer) for an existing type.
Strictly speaking, typedefs are almost never necessary. (The one exception, I think, involves the va_arg macro for variadic functions, which requires a type name that can be used in a certain way.)
It's very common to create a typedef for a struct type. In my opinion (which plenty of smart programmers don't share), this is poor style. For example, given:
struct foo { /* member declarations */ };
the type already has a perfectly good name, "struct foo". Why create another one? The counterargument is that it's more convenient to have a simple single-identifier name for the type.
The syntax for function types and pointer-to-function types is sufficiently convoluted that it can be worthwhile to simplify it by using typedefs. For example if you want a pointer to a function that takes a double argument and returns a double result, you can write:
double (*ptr)(double);
or you can write:
typedef double math_func(double); math_func *ptr;
Or, if you prefer, you can write:
typedef double (*math_func_ptr)(double);
Hiding pointerness behind a typedef is usually a bad idea, but in the case of a pointer-to-function type it's more defensible.
A typedef is also appropriate when you want an abstract data type, where code that uses the type shouldn't know anything about its internals. The type FILE, declared in <stdio.h> is a good example. (The use of all-caps isn't particularly consistent with modern style, which uses all-caps for macros, but it's been around for a very long time.)
And typedefs are often appropriate for numeric types. I *don't* mean something like
typedef unsigned int uint;
which does nothing but save you a little typing. I'm referring to a weaker form of data abstraction, where code that uses the typedef knows that it's an integer type, and whether it's signed or unsigned, but doesn't need to know *which* predefined type because it can vary from one system to another.
To summarize:
Use a typedef when the internal characteristics of the type are irrelevant to code that uses it (e.g., FILE).
Use a typedef when a named type can be implemented differently on different systems (e.g., int32_t, size_t).
Use a typedef to give a name to something that can otherwise only be referred to by some complicated syntax, particularly in the case of function types and pointer-to-function types.
If you're using a typedef just to save a few keystrokes, don't bother. Given "typedef unsigned int uint;", uint can never be anything other than unsigned int; just use its real name, "unsigned int". And if uint *can* be something other than unsigned int, "uint" is a lousy name.
Don't bother with typedefs for struct types unless you're doing the kind of data abstraction I discussed above -- but reasonable people differ on this.
And I can think of at least one exception to the above. I don't mind
typedef unsigned char byte;
"byte" can never be anything other than unsigned char, but assigning the name "byte" can make the usage clearer (i.e., this is raw data, not necessarily characters).
-- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> Nokia "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" |
| |
| | | Keith Thompson |  |
| Posted: Tue Sep 02, 2008 10:13 pm Post subject: Re: Typedef question |  |
jameskuyper@verizon.net writes: [...]
| Quote: | The second use I've seen is for simplifying type declarations. If you make a lot of use of unsigned char, it's convenient to use
typedef unsigned char uchar; [...] |
IMNSHO it's not convenient enough to justify using a typedef rather than just typing "unsigned char". For one thing, if I'm reading code that uses "uchar" I'll always have a nagging suspicion that somebody has decided it would be a cute idea to define it as something other than unsigned char (say, unsigned short or wchar_t).
-- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> Nokia "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" |
| |
| | | Guest |  |
| Posted: Tue Sep 02, 2008 10:35 pm Post subject: Re: Typedef question |  |
| |  | |
In article <1220384800.358284@news1nwk>, Eric Sosman <Eric.Sosman@sun.com> wrote:
| Quote: | Finally, the pointer thing. Even when a library traffics in pointers to private structs, the fact that they're pointers is usually something the caller must know, if for no other reason than to test a returned value against NULL. For this reason, I'd prefer to say that a function returns a `HashItem*' than a `HashItemPointer'; the latter just makes it harder to discern what you're dealing with. (Is this stance inconsistent with my preference for `HashItem' over `struct hashItem'? Probably, but as I said earlier I'm not going to war over it.)
|
I disagree that this is inconsistent; since pointerness is important for the user-programmer to know about, revealing it in the interface instead of hiding it behind a typedef is an easy way to save the user-programmer the trouble of making a trip to the documentation to discover it. Revealing structness in the same way doesn't give information that's useful (at least, it doesn't if your type is actually abstract; if you want to give direct information to (some of) the struct members, then the user-programmer also needs to know that it's a struct, and in that case hiding structness behind a typedef is also a Bad Idea).
I dislike hiding both properties behind typedefs; but my dislike for hiding structness is a purely aesthetic dislike, and my dislike for hiding pointerness is based on strong opinions about The Way Things Should Be and on experience with how useful it is to have the information in front of me while I'm editing code.
dave
-- Dave Vandervies dj3vande at eskimo dot com I am Aquarion, I am everywhere. There are only 120 real people on the Internet, and I'm three of them. --Aquarion in the scary devil monastery |
| |
| Page 1 of 2 .:. Goto page 1, 2 Next | |
|
|