David Brown <> writes:
> On 24/09/2012 09:26, Keith Thompson wrote:
>> I see a typedef as extra effort to hide the fact that the type
>> is a struct. And the plethora of different conventions (or lack
>> thereof) about the relationship between the struct tag and the
>> typedef name can cause confusion (though that can be avoided by
>> consistenly using the same identifier for both).
>>
>> The case against typedefs for struct types isn't as strong as the
>> case against typedefs for pointer types, but they're similar.
>
> (This is getting a bit off-topic, but I'll ask anyway.)
>
> Why would you have a case against typedefs for pointer types? You
> seem to have a general dislike of typedefs!
>
> I find pointer typedefs are often useful - and in some cases they are
> essential. I don't meant they are essential to writing code that will
> compile - but they are sometimes essential to writing code that is
> clear and unambiguous to the reader and the writer.
I've seen numerous articles here arguing against the use of typedefs for
pointer types. (I've also seen Windows code that uses them extensively.)
The semantics of pointer types and non-pointer types are so different
that I think it's important to be very explicit about which one you're
using. And "some_type*" is a sufficiently simple concept (for someone
familiar with C syntax and semantics) that I don't see much point in
hiding it behind a new name. It already has a name: "some_type*".
C's declaration syntax is admittedly obscure at times; the fact that the
type of a pointer to an array of 10 ints, is "int(*)[10]" is annoying.
But if I were using such a type, I'd consider typedef'ing the array
type, not the pointer type:
typedef int arr_10[10];
arr_10 *ptr;
I wouldn't quite say that I have a general dislike of typedefs.
I just think they're overused. If a typedef creates a truly abstract
type like "FILE", I have no problem with it. If it creates a name
for a type, when the underlying type can vary from one implementation
to another, or if the choice of name adds significant information,
that's fine too; examples are size_t and int32_t.
I don't necessarily *like* the way C defines types, but I'd rather
deal with that than add a layer on top of it to make it look *almost*
like what I would have preferred.
> In my work, const and volatile qualifiers are common, so it is not
> uncommon for the type of a pointer to contain many parts. This makes
> it hard to read, and easy to get wrong:
>
> uint8_t volatile * const p = ...;
>
> Is that a constant pointer to volatile data, or a volatile pointer to
> constant data, or a pointer to a volatile constant?
>
> typedef volatile uint8_t *pVolUint8_t;
> const pVolUint8_t p = ...;
>
> Here there is no doubt what is volatile, and what is const, and how
> the parts are related.
That's a good point. Personally, I haven't run into many cases where
that's much of an issue.
[...]
> Typedefs are even more important if you are talking about function pointers.
An alternative is to typedef the function type, and then use the
explicit "*" for the pointer-to-function type. I don't expect to
convince you that that's better.
> Naming conventions are also very useful here - all my pointer types
> being with "p" (or "P" if you prefer), and all function pointer types
> begin with "f" (or "F" if you prefer).
That's fine until you mix your code with code written by somebody else
who doesn't follow your conventions -- such as the C standard library.
--
Keith Thompson (The_Other_Keith)
kst- <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"