Typedefs allow the programmer to create an alias for a data type, and use the aliased name instead of the actual type name. To declare a typedef, simply use the typedef keyword, followed by the type to alias, followed by the alias name:
typedef long miles; // define miles as an alias for long // The following two statements are equivalent: long nDistance; miles nDistance;
A typedef does not define new type, but is just another name for an existing type. A typedef can be used anywhere a regular type can be used.
Typedefs are used mainly for documentation and legibility purposes. Data type names such as char, int, long, double, and bool are good for describing what type of variable something is, but more often we want to know what purpose a variable serves. In the above example, long nDistance does not give us any clue what units nDistance is holding. Is it inches, feet, miles, meters, or some other unit? miles nDistance makes it clear what the unit of nDistance is.
This is also true of function return types. Which of the following is easier to decipher?
typedef int testScore; int GradeTest(); testScore GradeTest();
What is the first GradeTest() returning? A grade? The number of questions missed? The student’s ID number? An error code? Who knows! Int does not tell us anything. Using a return type of testScore makes it obvious that the function is returning a type that represents a test score.
Furthermore, typedefs allow you to change the underlying type of an object without having to change lots of code. For example, if you were using a short to hold a student’s ID number, but then decided you needed a long instead, you’d have to comb through lots of code and replace short with long. It would probably be difficult to figure out which shorts were being used to hold ID numbers and which were being used for other purposes.
However, with a typedef, all you have to do is change typedef short studentID to typedef long studentID and you’re done. Precaution is mandatory when changing the type of a typedef! The new type may have comparison or integer/floating point division issues that the old type did not.
Note that typedefs don’t mix particularly well with Hungarian Notation, and allow you to skirt some of the issues that using Hungarian Notation tries to prevent (such as being able to change a variable’s type without having to examine the code for areas where changing the type will be problematic).
Because typedefs do not define new types, they can be intermixed like normal data types. Even though the following does not make sense conceptually, syntactically it is valid C++:
typedef long miles; typedef long speed; miles nDistance = 5; speed nMhz = 3200; // The following is okay, because nDistance and nMhz are both type long nDistance = nMhz;
Platform independent coding
One big advantage of typedefs is that they can be used to hide platform specific details. On some platforms, an integer is 2 bytes, and on others, it is 4. Thus, using int to store more than 2 bytes of information can be potentially dangerous when writing platform independent code.
Because char, short, int, and long give no indication of their size, it is fairly common for cross-platform programs to use typedefs to define aliases that include the type’s size in bits. For example, int8 would be an 8-bit integer, int16 a 16-bit integer, and int32 a 32-bit integer. Using typedef names in this manner helps prevent mistakes and makes it more clear about what kind of assumptions have been made about the size of the variable.
In order to make sure each typedef type resolves to a type of the right size, typedefs of this kind are typically used in conjunction with the preprocessor:
#ifdef INT_2_BYTES typedef char int8; typedef int int16; typedef long int32; #else typedef char int8; typedef short int16; typedef int int32; #endif
On machines where integers are only 2 bytes, INT_2_BYTES can be #defined, and the program will be compiled with the top set of typedefs. On machines where integers are 4 bytes, leaving INT_2_BYTES undefined will cause the bottom set of typedefs to be used. In this way, int8 will resolve to a 1 byte integer, int16 will resolve to a 2 bytes integer, and int32 will resolve to a 4 byte integer using the combination of char, short, int, and long that is appropriate for the machine the program is being compiled on.
4.7 — Structs
|
Index
|
4.5 — Enumerated types
|
4.7 — Structs
Index
4.5 — Enumerated types
Shouldn’t the following:
#ifdef INT_2_BYTES
typedef int8 char;
typedef int16 int;
typedef int32 long;
#else
typedef int8 char;
typedef int16 short;
typedef int32 int;
#endif
be like this:
#ifdef INT_2_BYTES
typedef char int8;
typedef int int16;
typedef long int32;
#else
typedef char int8;
typedef short int16;
typedef int int32;
#endif
Aren’t int8, int16, int32 arbitrary types to use instead of char, short, int, long?
[ Yes. The typedef declaration is defined as:
typedef type-declaration synonym;so you are correct. I fixed the example. -Alex ]Is there any reason typedefs should be used rather than #defines?
typedefs are generally safer and harder to inadvertently screw up than #defines.
Here’s an example of where using a typedef is better than using a #define:
In the second example, you were probably expecting pW to be of type int*, but it’s of type int instead!
just so you know, the part of your comment should be
just remember that defines and typedefs go in the reverse order
Ok I wrote a program like this to calculate distance in km and I used DistanceCovered as alias for the type double:
#include <iostream> typedef double DistanceCovered; DistanceCovered InKilomtres() { using namespace std; float speed; cout << "Please enter the speed in km/hr:" << endl; cin >> speed; float time; cout << "Please enter the time taken in hours:" << endl; cin >> time; return speed * time; }It is returning me something like this when I run it in the g++ compiler:
/usr/lib/gcc/i486-linux-gnu/4.3.3/../../../../lib/crt1.o: In function `_start’:
/build/buildd/glibc-2.9/csu/../sysdeps/i386/elf/start.S:115: undefined reference to `main’
I’m sure something is wrong with my code but I can’tfind what!
Well what is obviously missing is the int main() section. I took the code and copied it and added the int main() section and it worked perfectly.
#include "stdafx.h" #include <iostream> typedef double DistanceCovered; DistanceCovered InKilomtres() { using namespace std; float speed; cout << "Please enter the speed in km/hr:" << endl; cin >> speed; float time; cout << "Please enter the time taken in hours:" << endl; cin >> time; //I added this because it was not printing the answer anywhere. cout << "You travelled " << speed * time << " kilometers." << endl; return speed * time; } int main() { InKilomtres(); return 0; }Sorry, but I don’t really understand this part of the tutorials.
What I’m guessing is that:
is the same as:
?
exactly correct.