Page 1 of 3

Pros and cons of typedefing integers

Posted: Wed Jul 08, 2009 5:15 am
by Jezze
Hi,

I wonder what is the pros and cons of using definitions like

typedef unsigned char uint8_t;
typedef unsigned long uint32_t;

So far I've come to the conclusion that

Pros:
It is easy to see how many bytes it can hold.
It is shorter to write

Cons:
If I have a function like void puts(uint8_t *s) the compiler will give a warning if called with puts("Hello");

Can someone put some clarity into this? Should I use it at all?

Re: Pros and cons of typedefing integers

Posted: Wed Jul 08, 2009 5:45 am
by Solar
Like everything in programming, typedef's are best handled in limited dosage.

There is no sense in typedef'ing an integer simply to use a different name. Actually, that's the worst thing you can do with typedef's, because you are deliberately hiding useful information (what an object actually is). As nice as

Code: Select all

typedef std::vector< std::string > StringVector;
might be at first glance, it's confusing because the other guy has to look up StringVector first if he wants to be sure what it is. And it gets positively evil with code like this:

Code: Select all

typedef StringVector TableRow;
(Actual in-the-wild code I've encountered.) Now the other guy has to do two lookups to determine what he can and can't do with a TableRow object...

(All this isn't quite as bad with mere integers, but you get the idea.)

Where they do come in handy is when you want to add information. Integer sizes differ between platforms, but sometimes you need an integer that is exactly 32 bits wide. Code like:

Code: Select all

typedef int int32_t;
or, respectively,

Code: Select all

typedef long int32_t;
or whatever works for your platform, allows you to use int32_t throughout the rest of the code, with the typedef'ed name adding information that a mere 'int' or 'short' cannot convey. You'd still be using 'int' for loop counters or 'size_t' for array indices, because that's what they're for, but you'd use int32_t where the exact width is important.

Later, if you switch platforms, all you have to do is changing the typedef in one location. (Or, of course, use <stdint.h> which already does this for you.)

At the end, integer typedef's are usually unnecessary, and the few cases where they are really useful are mostly covered by the language standard already.

Oh, they're useful in one other regard: Function pointers. Their syntax still dazzles me, and I much prefer looking up the correct syntax once and use a typedef for the rest of the code.

As for your conversion warning regarding puts( uint8_t * s ), that's one of the places where you're using a typedef for the wrong thing. puts() takes a char pointer, not a pointer to an unsigned integer of exactly 8 bits length. It's absolutely OK that the compiler buggers you about that...

Re: Pros and cons of typedefing integers

Posted: Wed Jul 08, 2009 6:27 am
by MasterLee
Jezze wrote:Hi,
If I have a function like void puts(uint8_t *s) the compiler will give a warning if called with puts("Hello");
void puts(constant uint8_t *s) will produce no warning when called with puts("Hello");

The only use i knew for typedef is to prevent users from using the wrong variables.
For Example the follwing typdefs will prevent programmer for accidently swaping Menu and Window handles or even worse filling in some generic handle:

typedef void *PVOID;
typedef PVOID HANDLE;
typedef HANDLE HMENU;
typedef HANDLE HWND;
typedef HANDLE HINSTANCE;
typedef unsigned long DWORD;
typedef void *LPVOID;

HWND CreateWindowEx(
DWORD dwExStyle,
LPCTSTR lpClassName,
LPCTSTR lpWindowName,
DWORD dwStyle,
int x,
int y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam
);

Re: Pros and cons of typedefing integers

Posted: Wed Jul 08, 2009 7:01 am
by Creature
Jezze wrote: Cons:
If I have a function like void puts(uint8_t *s) the compiler will give a warning if called with puts("Hello");

Can someone put some clarity into this? Should I use it at all?
That's not a con, that's because you're actually using a cast to get the right type.

"Hello" has type:

Code: Select all

const signed char *
This (*usually*) is the same as:

Code: Select all

const char *
which will be cast to

Code: Select all

unsigned char *
by your 'puts' function. That's why you're getting a warning.

In my opinion, typedefs can indeed be useful, but whether you use them is really up to you. If you like the typedefs more than the original 'names', you should use them. I always use 'byte' for 'unsigned char' and 'word' for 'unsigned short'. I usually only use 'dword' in structures because I think 'unsigned' just looks better (don't ask me why).

Besides that, I think the Win32 typedefs are really ugly. All the capitalized WORD, DWORD, BYTE and such just bloat the code and make it unreadable IMO.

Re: Pros and cons of typedefing integers

Posted: Wed Jul 08, 2009 8:23 am
by Solar
MasterLee wrote: typedef void *PVOID;
typedef PVOID HANDLE;
typedef HANDLE HMENU;
typedef HANDLE HWND;
typedef HANDLE HINSTANCE;
typedef unsigned long DWORD;
typedef void *LPVOID;
Note how beautifully that fits together with what I said about where typedef's make no sense but simply confuse the developer.

HINSTANCE is HWND is HMENU, all of which are really HANDLE which is PVOID which is a void *... and all of this cannot be done with expressive variable names... why?

Re: Pros and cons of typedefing integers

Posted: Wed Jul 08, 2009 8:50 am
by Firestryke31
Because it's nice to know "this is a handle to a window" rather than "this is a pointer to a location in memory that could be anything."

Re: Pros and cons of typedefing integers

Posted: Wed Jul 08, 2009 9:47 am
by Jezze
Thanks for all the valuable feedback. I have a much better picture of how I want my OS to implement typedefs.

Re: Pros and cons of typedefing integers

Posted: Wed Jul 08, 2009 9:50 am
by gravaera
MasterLee wrote:
Jezze wrote:Hi,
If I have a function like void puts(uint8_t *s) the compiler will give a warning if called with puts("Hello");
void puts(constant uint8_t *s) will produce no warning when called with puts("Hello");

The only use i knew for typedef is to prevent users from using the wrong variables.
For Example the follwing typdefs will prevent programmer for accidently swaping Menu and Window handles or even worse filling in some generic handle:

typedef void *PVOID;
typedef PVOID HANDLE;
typedef HANDLE HMENU;
typedef HANDLE HWND;
typedef HANDLE HINSTANCE;
typedef unsigned long DWORD;
typedef void *LPVOID;

HWND CreateWindowEx(
DWORD dwExStyle,
LPCTSTR lpClassName,
LPCTSTR lpWindowName,
DWORD dwStyle,
int x,
int y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam
);
Oh...you have no idea how much I HATE seeing people ABUSE typedefs like that...

A (void *) is not in any way even distantly related to the concept of a window handler. What the hell? Couldn't you just use comments? You just did about ten different typedefs on ONE type. That makes NO SENSE. It's TEN times easier to understand that "I'm working with a (void *) variable here.

But telling me that I have to keep track of ALL of these typedefs is nothing but IRRITATING. You're not making the code any more understandable. You're making it worse. That means that every time I encounter your typedef, I have to strain my memory to remember exactly what you went and renamed.

And how on earth is a window handler supposed to be related to a void *? The first thing you do is confuse everyone but yourself into thinking that you've defined a class, or a structure that has variables related to a window. Tell me HOW on earth anyone is supposed to figure out that you intended for a window typedef made to mean a void *?

I hope to GOD you don't do this at work and frustrate everyone else. If you do, please, I'm urging you to be considerate to other people, and stop. Please. It's not funny.

Re: Pros and cons of typedefing integers

Posted: Wed Jul 08, 2009 9:56 am
by Solar
Firestryke31 wrote:Because it's nice to know "this is a handle to a window" rather than "this is a pointer to a location in memory that could be anything."
Again, that's why variable names were invented. I don't care if you call it hWndMyApp or MyApp_Window or whatever, but the type of a variable is what defines it's functionality.

I suppose it's something that doesn't appear as self-explanatory to a C coder as it does to a C++ coder...

Re: Pros and cons of typedefing integers

Posted: Wed Jul 08, 2009 10:04 am
by gravaera
Solar wrote:
Firestryke31 wrote:Because it's nice to know "this is a handle to a window" rather than "this is a pointer to a location in memory that could be anything."
Again, that's why variable names were invented. I don't care if you call it hWndMyApp or MyApp_Window or whatever, but the type of a variable is what defines it's functionality.

I suppose it's something that doesn't appear as self-explanatory to a C coder as it does to a C++ coder...
Somebody say AMEN. "Amen."

I can't hear ya. Somebody: Say A-men. "A-MEN!"

Re: Pros and cons of typedefing integers

Posted: Wed Jul 08, 2009 10:07 am
by Colonel Kernel
holypanl wrote:I hope to GOD you don't do this at work and frustrate everyone else. If you do, please, I'm urging you to be considerate to other people, and stop. Please. It's not funny.
Calm down dude... Yes, those typedef's suck, but they're from the Win32 API. :) MasterLee almost certainly did not invent them.

Re: Pros and cons of typedefing integers

Posted: Wed Jul 08, 2009 10:22 am
by Firestryke31
Solar wrote:
Firestryke31 wrote:Because it's nice to know "this is a handle to a window" rather than "this is a pointer to a location in memory that could be anything."
Again, that's why variable names were invented. I don't care if you call it hWndMyApp or MyApp_Window or whatever, but the type of a variable is what defines it's functionality.

I suppose it's something that doesn't appear as self-explanatory to a C coder as it does to a C++ coder...
What about when you're looking at the function prototypes? How are you supposed to know when you can use any old void * and when only this special void * works? And how does using regular void *s keep you from accidentally using a HMENU in an HWND parameter?

I do admit they could just as well have done this instead of the typedef soup:
typedef void *PVOID;
typedef void *HANDLE;
typedef void *HMENU;
typedef void *HWND;
typedef void *HINSTANCE;
typedef unsigned long DWORD;
typedef void *LPVOID;

I guess I'm just different in that I don't care how they went about doing it, as long as it works. I mean, what extra benefit do you get from knowing an HWND is really a void *? Hell, I thought they were typedefed to int, but knowing this has no effect on what I do, since all I care is that the compiler will complain if I accidentally use a HMENU instead of an HWND.

Re: Pros and cons of typedefing integers

Posted: Wed Jul 08, 2009 10:34 am
by Solar
Firestryke31 wrote:What about when you're looking at the function prototypes? How are you supposed to know when you can use any old void * and when only this special void * works?
You mean you need it to read "HWND hWndParent" instead of "void * hWndParent" just in case you missed the hint with the variable name?
And how does using regular void *s keep you from accidentally using a HMENU in an HWND parameter?
Erm... your typedef's don't protect from that, either? (At least with GCC they don't...)

Re: Pros and cons of typedefing integers

Posted: Wed Jul 08, 2009 10:38 am
by gravaera
Firestryke31 wrote:
Solar wrote:
Firestryke31 wrote:Because it's nice to know "this is a handle to a window" rather than "this is a pointer to a location in memory that could be anything."
Again, that's why variable names were invented. I don't care if you call it hWndMyApp or MyApp_Window or whatever, but the type of a variable is what defines it's functionality.

I suppose it's something that doesn't appear as self-explanatory to a C coder as it does to a C++ coder...
What about when you're looking at the function prototypes? How are you supposed to know when you can use any old void * and when only this special void * works? And how does using regular void *s keep you from accidentally using a HMENU in an HWND parameter?
But aren't they both the same thing...? How could typedeffing the void * twice provide protection? Are we really analysing the same programing language?

EDIT: I think I just realized why you think it provides type protection. You believe that a typedef is like a cloning of the type under a different name. i.e: It's like creating a new type altogether.

Typedefs create an ALIAS for a type. But the compiler will translate the HWIND etc, all the way back down to void *. And it won't type check to see if you used HWIND consistently as the return type which was declared as returning HWIND. As far as the compiler is concerned, whenever it sees HWIND, it's just supposed to replace that with void *. It's not a new type.

Borland C++ compiler and GCC, and even Miracle C don't provide any type checking on typedefs.

Re: Pros and cons of typedefing integers

Posted: Wed Jul 08, 2009 10:46 am
by Creature
If you ask me, Microsoft was just too lazy to create actual pointers to objects and it went like this:
  • Coder 1: "Oh my god, so many types, so many functions!"
  • Coder 2: "Hell, this sucks, let's just use a void pointer for every function to make it easier."
  • Coder 3: "You can't do that, then it'll look like it's low-level and dangerous and application C/C++ programmers will think using void pointers in high-level applications is bad!"
  • Coder 2: "Fine, we'll just typedef the lot a million times to make it seem as if it's a real structure and not a void pointer."
Typedefs explained according to Microsoft.

The few times I used the Win32 API to code things, I remember I used to replace HANDLE and such with the actual type it lead to, because it was just much clearer IMO.