Using typedef to Curb Miscreant Code

typedef declaration, or a typedef for short, creates a new name for an existing type. As such, it is often used in writing more aesthetic and readable code. Aesthetics not withstanding, typedefs can also hide unwieldy syntactic constructs and platform-dependent datatypes, thereby enhancing portability and future maintenance. The following sections show how to exert the power of typedef while avoiding common traps.

How to create platform-independent datatypes and hide cumbersome, if not unintelligible, syntax?

Use typedefs to create synonyms for existing types.

Defining Mnemonic Type Names
The most common use of typedefs is creating mnemonic type names that document the programmer’s intention. The type being declared appears in the position of a variable’s name, right after the keyword ‘typedef’. For example,

typedef int size;

This declaration defines a synonym for int called size. Notice that a typedef doesn’t create a new type; it merely adds a synonym for some existing type. You can use size in any context that requires int:

void measure(size * psz); size array[4];size len = file.getlength();std::vector  vs; 

typedefs may also disguise composite types such as pointers and arrays. For example, instead of repeatedly declaring an array of 81 characters like this:

char line[81];char text[81];

Define a typedef that will be used every time you need an array of the same type and size:

typedef char Line[81];  Line text, secondline;getline(text);

Similarly, hide pointer syntax like this:

typedef char * pstr;int mystrcmp(pstr, pstr);

This brings us to the first typedef trap. The standard function strcmp() takes two arguments of type ‘const char *’. Therefore, it might be tempting to declare mystrcmp() like this:

int mystrcmp(const pstr, const pstr); 

This is wrong, though. The sequence ‘const pstr’ is interpreted as ‘char * const’ (a const pointer to char), rather than ‘const char *’ (a pointer to const char). You can easily solve this problem, though:

typedef const char * cpstr; int mystrcmp(cpstr, cpstr); //now correct

Remember: Whenever you declare a typedef for a pointer, adding const to the resulting typedef name makes the pointer itself const, not the object.

Code Simplification
The typedefs I’ve shown thus far behave like a #define macro that substitutes a synonym with its actual type. Yet unlike macros, typedefs are interpreted at compile-time, thereby enabling the compiler to cope with textual substitutions that are beyond the preprocessor’s capabilities. For example,

typedef int (*PF) (const char *, const char *);

This declaration introduces the type PF as a synonym for ‘pointer to function taking two const char * arguments and returning int’. In the following function declaration, the use of this typedef is indispensable:

PF Register(PF pf);

Register() takes a callback function of type PF and returns the address of a function with a similar signature that was previously registered. Take a deep breath. I’m about to show you how this declaration would look without a typedef:

int (*Register (int (*pf)(const char *, const char *))) (const char *, const char *); 

Few programmers understand what it means, not to mention its risk of introducing mistakes into such convoluted code. Obviously, the use of a typedef here isn’t a prerogative but a must. “OK, but does anyone write such code anyway?” the skeptics among you are probably asking. A quick glance at the header file reveals signal(), a function which has a similar interface.

typedef and Storage Specifiers
Surprising as it may sound, typedef is a storage class specifier, just like auto, extern, mutable, static and register. This doesn’t mean that typedef actually affects the storage characteristics of an object; it only means that syntactically, typedef declarations look like declarations of static, extern etc., variables. This brings us to trap #2:

typedef register int FAST_COUNTER; //error

This won’t compile. The problem is that you can’t have multiple storage class specifiers in a declaration. Because the token typedef already occupies the position of a storage class specifier, you can’t use register (or any other storage class specifier) in a typedef declaration.

Facilitating Cross-platform Development
typedefs have another important use, namely defining machine-independent types. For example, you can define a floating point type called REAL that has the highest precision available on the target machine:

typedef long double REAL; 

On machines that don’t support long double, this typedef will look like this:

typedef double REAL;  

And on machines that don’t even support double:

typedef float REAL;  

You can compile applications that use the type REAL on every platform without making any changes to the source file. The only thing that will change is the typedef itself. In most cases, even this tiny change will be totally automatic thanks to the wonders of conditional compilation. Nifty, isn’t it? The Standard Library uses typedefs extensively to create such platform-independent types: size_t, ptrdiff_t and fpos_t are a few examples. Likewise, typedefs such as std::string and std::ofstream hide the long and nearly unintelligible template specializations basic_string, allocator > and basic_ofstream >, respectively.

Share the Post:
Share on facebook
Share on twitter
Share on linkedin


The Latest

6 Tips for Setting Up a Decentralized Exchange

6 Tips for Setting Up a Decentralized Exchange

There’s no doubt that cryptocurrency is a complex and divisive topic in the modern financial landscape. There are those who are convinced that it’s nothing more than a bubble, but both who are well-informed are able to see the ways in which cryptocurrency can help them both build their fortune

user experience with someone on their phone

5 Ways to Improve Your Customers’ User Experience

They say you can’t judge a book by its cover, but just because they say that doesn’t mean it’s true. Consider how often you choose one sort of product over another just because it appeals to you. Then think about how often you’ve stopped using something because, simply put, it

How to Manage Your Finances after Buying a Home

How to Manage Your Finances after Buying a Home

Buying a home is a milestone in the journey of life – it’s one way to invest your money and create lasting memories. Now you know everything about a home purchase, home mortgage, and what is a conventional 97 loan but do you know what’s next after you sign the

Windows Logging is one of the vital aspects of any Windows system administration. However, it is mostly overlooked until the system develops a problem. This is because logs contain important information needed to troubleshoot and resolve system issues.

The Fundamentals of Windows Logging

Windows Logging is one of the vital aspects of any Windows system administration. However, it is mostly overlooked until the system develops a problem. This is because logs contain important information needed to troubleshoot and resolve system issues. Without it, tech experts might find it difficult to track a computer’s

Interstitial Ads: Best Practices for Successful Campaigns

Interstitial Ads: Best Practices for Successful Campaigns

Interstitial Ads: Best Practices for Successful Campaigns Interstitial ads are full-screen advertisements that appear to grasp the attention of on-site prospects, creating opportunities for brands seeking effective ways to communicate their proposition of value. With such an attention-grabbing format and high-impact visuals, it’s no wonder why interstitial advertising is proving