Nurav
Nurav

Reputation: 177

what is the use of using the typedef and what does it signifies?

I came across the code and it was kind of strange to me I am unable to understand what it means.

typedef struct alpha *Abc;

this is where Abc is defined;

struct alpha{
     Abc s;//what does this mean
}

also some where in function it is used like this

Abc iAmFunc(Abc beta,int a){
       some thing is performed
       return variable of type Abc
}

I dont understand the purpose of doing this can anyone explain me!!

Upvotes: 1

Views: 1998

Answers (4)

John Bode
John Bode

Reputation: 123448

I want to expand on this part of Klutt's excellent answer a bit:

Be restrictive with typedefs. Often they just clutters the code and makes it harder to follow. Use them when they fill a purpose. Be especially restrictive with aliasing pointers. I only use them for function pointers and completely opaque objects.

What Klutt is talking about here is abstraction - hiding implementation details of a type from the person using it. Think about the FILE type in the standard library (stdio.h) - it is almost always a typedef name for a reasonably complex struct type.

However, the standard library doesn't just create the typedef name, it also provides a set of functions to create and manipulate FILE objects for you. You never manipulate the contents of a FILE object directly, you always use the stdio functions to interact with it. The abstraction is complete in that you can do everything necessary with a FILE without having to know any details of its implementation.

Contrast that with something like

typedef struct coord { double lat, lon; } Coordinates;

Coordinates c;
c.lat = 20.0;
c.lon = 47.5;
...
printf( "Coordinates: {%f:%f}\n", c.lat, c.lon );

where all I've done is create the typedef name Coordinates. In order to use an object of Coordinates type, you have to know that it's a struct type with two members of type double named lat and lon. The abstraction is "leaky" - details of the implementation "leak" out to the programmer.

To create a proper abstraction, I would need to expose only the typedef name without exposing its implementation, and I would need to provide a set of functions to manipulate coordinate types:

// Coord.h

/**
 * Forward declare the struct type; the type is incomplete at this point,
 * and will be completed in Coord.c
 */
struct coord;

/**
 * Create the typedef name - you can create typedef names for (and pointers 
 * to) incomplete types.
 */ 
typedef struct coord Coordinates; 

/**
 * Create a new Coordinates object and return a pointer to it.  Since the
 * Coordinates type is *incomplete* at this point, we cannot declare an
 * object of that type nor a function that returns an object of that type.
 * We can only declare things that are *pointers* to that type.  
 */
Coordinates *newCoord( double, double ); 

/**
 * Set the coordinates on an existing Coordinates object
 */
setCoord( Coordinates *, double, double ); 

/**
 * Compute the bearing from one set of coordinates to the other
 */
double bearing( const Coordinates *, const  Coordinates * );

/**
 * Return a string representation of the coordinate pair (suitable for
 * passing to printf and other display functions)
 */     
char *format( const Coordinates * ); 

etc., etc., etc.

This is why both Klutt and I recommend that you not use typedef just to rename things or avoid using the struct keyword. Use it as part of creating a complete abstraction, or don't use it at all.

Also, DO NOT HIDE POINTERS BEHIND typedefs!!! It is a practice that will bite you in the ass at some point. Pointer semantics are special and should not be hidden.

Upvotes: 1

JVApen
JVApen

Reputation: 11317

typedef is used to give something a new name. For example typedef int ID. This makes a new type alias for int with the name ID, allowing you to use it. For example:

struct S
{
   ID id;
};

This is especially useful to make your code more readable, as having 4 ints in a class/struct ain't self explanatory.

In modern C++, we tend to step away from typedef and use using instead.

For example: using ID = int; this removes confusion when reading as it's obvious which is the new name and which the old. Though, it improves even more for pointers, like: using IntPtr = int *; iso typedef int *IntPtr; or function pointers: using IntIntFunc = int(*)(int); iso typedef int(*IntIntFunc)(int);

In C++, you can even take this a step further, and use it to make new strong types, see Strong types for strong interfaces - fluentcpp.com for the details. (Also works with typedef)

The short version:

using ID = NamedType<int, struct IDTag>;
ID id = ID{0}; // OK
int width = 5;
id = width; // Compilation error
id = ID{width}; // OK again

This can prevent bugs because of typos where you accidentally mix types. A more useful place where this could make sense:

struct Rectangle { Height h; Width w; };
Rectangle r{5, 3}; // Doesn't compile
Rectangle r{Width{5}, Height{3}}; // Doesn't compile
Rectangle r{Height{3}, Width{5}}; // Does compile

Upvotes: 0

klutt
klutt

Reputation: 31296

Note, this is for C and not C++. Maybe it's applicable for C++ too, but I don't know.

typedef a b makes b an alias for a

What typedef struct alpha *Abc; is to make Abc an alias for struct alpha *. After you have created this, these two are equivalent:

struct alpha *ptr;
Abc ptr;

There are a few different uses for this:

It reduces how much you need to write. You can skip the struct word for instance. Many would say that this is NOT a good reason to use typedef.

It can give a more descriptive name for certain things. Examples:

typedef char* string; // I would never use this. It's just an example.
typedef int[3] vector; // However, this is something I would consider.

It can make it easier to change the type for a large code base in certain situations. Suppose you have this code:

int16_t foo(int16_t a)
{
    int16_t b = a+1;
    for(int16_t = 0; i<b; i++) {
...

And later you realize that it would be a good idea to change to int32_t instead. If the code instead looked like this, you would only need to change one line:

typedef int16_t T
T foo(T a)
{
    T b = a+1;
    for(T = 0; i<b; i++) {
...

Be restrictive with typedefs. Often they just clutters the code and makes it harder to follow. Use them when they fill a purpose. Be especially restrictive with aliasing pointers. I only use them for function pointers and completely opaque objects. Same thing with structs and unions. IMHO, 99% of the typedefs I see in questions here at SO are not necessary and seems to be there just because people think that they should.

If you consider typedefing a struct, ask yourself if it would be good to anyone reading the code to know that a declaration is a struct. If yes, declare it with the struct keyword. Of course you could invent something like typedef struct my_struct my_struct_s but is it really worth the effort? I'd say no.

It can be worth noting that C has something that seems like a simple form of namespace. This means that this completely valid:

typedef struct mystruct mystruct;
struct mystruct a;
mystruct b;

So mystruct is an alias for mystruct. And this is what you should do, unless you have a good reason not to.

I once wrote a related answer and if that answer wasn't so heavily focused on just structs, I would have made this question a duplicate.

In comments below, I saw this example:

typedef unsigned short int int_16;

and this is a HORRIBLE example. First, int_16 gives the impression that it is a signed type, which it is clearly not. Secondly, short int (and its unsigned counterpart) is guaranteed to have at least 16 bits, but int_16 gives the impression that it have exactly 16 bits. Depending on what you want, there are a few good ones in the standard:

  • int16_t and uint16_t - Exactly 16 bits
  • int_least16_t and uint_least16_t - At least 16 bits
  • int_fast16_t and uint_fast16_t - At least 16 bits, but hint to the compiler that you want the fastest type

Upvotes: 1

DNT
DNT

Reputation: 2395

The typedef defines a pointer type to struct alpha with type name Abc. Because of this, Abc s; translates to struct alpha *s;

Upvotes: 3

Related Questions