Pros and cons of typedefing integers
Pros and cons of typedefing integers
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?
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?
Fudge - Simplicity, clarity and speed.
http://github.com/Jezze/fudge/
http://github.com/Jezze/fudge/
Re: Pros and cons of typedefing integers
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
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:
(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:
or, respectively,
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...
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;
Code: Select all
typedef StringVector TableRow;
(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;
Code: Select all
typedef long int32_t;
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...
Every good solution is obvious once you've found it.
Re: Pros and cons of typedefing integers
void puts(constant uint8_t *s) will produce no warning when called with puts("Hello");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");
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
);
50₰
Re: Pros and cons of typedefing integers
That's not a con, that's because you're actually using a cast to get the right type.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?
"Hello" has type:
Code: Select all
const signed char *
Code: Select all
const char *
Code: Select all
unsigned char *
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.
When the chance of succeeding is 99%, there is still a 50% chance of that success happening.
Re: Pros and cons of typedefing integers
Note how beautifully that fits together with what I said about where typedef's make no sense but simply confuse the developer.MasterLee wrote: typedef void *PVOID;
typedef PVOID HANDLE;
typedef HANDLE HMENU;
typedef HANDLE HWND;
typedef HANDLE HINSTANCE;
typedef unsigned long DWORD;
typedef void *LPVOID;
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?
Every good solution is obvious once you've found it.
- Firestryke31
- Member
- Posts: 550
- Joined: Sat Nov 29, 2008 1:07 pm
- Location: Throw a dart at central Texas
- Contact:
Re: Pros and cons of typedefing integers
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."
Owner of Fawkes Software.
Wierd Al wrote: You think your Commodore 64 is really neato,
What kind of chip you got in there, a Dorito?
Re: Pros and cons of typedefing integers
Thanks for all the valuable feedback. I have a much better picture of how I want my OS to implement typedefs.
Last edited by Jezze on Wed Jul 08, 2009 9:57 am, edited 1 time in total.
Fudge - Simplicity, clarity and speed.
http://github.com/Jezze/fudge/
http://github.com/Jezze/fudge/
- gravaera
- Member
- Posts: 737
- Joined: Tue Jun 02, 2009 4:35 pm
- Location: Supporting the cause: Use \tabs to indent code. NOT \x20 spaces.
Re: Pros and cons of typedefing integers
Oh...you have no idea how much I HATE seeing people ABUSE typedefs like that...MasterLee wrote:void puts(constant uint8_t *s) will produce no warning when called with puts("Hello");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");
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
);
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.
17:56 < sortie> Paging is called paging because you need to draw it on pages in your notebook to succeed at it.
Re: Pros and cons of typedefing integers
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.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."
I suppose it's something that doesn't appear as self-explanatory to a C coder as it does to a C++ coder...
Every good solution is obvious once you've found it.
- gravaera
- Member
- Posts: 737
- Joined: Tue Jun 02, 2009 4:35 pm
- Location: Supporting the cause: Use \tabs to indent code. NOT \x20 spaces.
Re: Pros and cons of typedefing integers
Somebody say AMEN. "Amen."Solar wrote: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.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."
I suppose it's something that doesn't appear as self-explanatory to a C coder as it does to a C++ coder...
I can't hear ya. Somebody: Say A-men. "A-MEN!"
17:56 < sortie> Paging is called paging because you need to draw it on pages in your notebook to succeed at it.
- Colonel Kernel
- Member
- Posts: 1437
- Joined: Tue Oct 17, 2006 6:06 pm
- Location: Vancouver, BC, Canada
- Contact:
Re: Pros and cons of typedefing integers
Calm down dude... Yes, those typedef's suck, but they're from the Win32 API. MasterLee almost certainly did not invent them.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.
Top three reasons why my OS project died:
- Too much overtime at work
- Got married
- My brain got stuck in an infinite loop while trying to design the memory manager
- Firestryke31
- Member
- Posts: 550
- Joined: Sat Nov 29, 2008 1:07 pm
- Location: Throw a dart at central Texas
- Contact:
Re: Pros and cons of typedefing integers
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?Solar wrote: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.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."
I suppose it's something that doesn't appear as self-explanatory to a C coder as it does to a C++ coder...
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.
Owner of Fawkes Software.
Wierd Al wrote: You think your Commodore 64 is really neato,
What kind of chip you got in there, a Dorito?
Re: Pros and cons of typedefing integers
You mean you need it to read "HWND hWndParent" instead of "void * hWndParent" just in case you missed the hint with the variable name?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?
Erm... your typedef's don't protect from that, either? (At least with GCC they don't...)And how does using regular void *s keep you from accidentally using a HMENU in an HWND parameter?
Every good solution is obvious once you've found it.
- gravaera
- Member
- Posts: 737
- Joined: Tue Jun 02, 2009 4:35 pm
- Location: Supporting the cause: Use \tabs to indent code. NOT \x20 spaces.
Re: Pros and cons of typedefing integers
But aren't they both the same thing...? How could typedeffing the void * twice provide protection? Are we really analysing the same programing language?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? And how does using regular void *s keep you from accidentally using a HMENU in an HWND parameter?Solar wrote: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.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."
I suppose it's something that doesn't appear as self-explanatory to a C coder as it does to a C++ coder...
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.
17:56 < sortie> Paging is called paging because you need to draw it on pages in your notebook to succeed at it.
Re: Pros and cons of typedefing integers
If you ask me, Microsoft was just too lazy to create actual pointers to objects and it went like this:
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.
- 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."
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.
When the chance of succeeding is 99%, there is still a 50% chance of that success happening.