Atul
Atul

Reputation: 4320

Pointer declaration convention in C

This might have been discussed before. But I couldn't find any reference so far. So thought to post it.

When we declare pointer (say of int type) we write,

int* pointer;

Where int* is data type (And therefore we can do typedef int* PTR_TO_INT; and then can declare variables of type PTR_TO_INT)

But when we want to declare multiple pointers, why do we need to affix * to each of them?

int* pointer1, pointer2, pointer3; // Only first is pointer. Rest are integers

While in this case it's not same convention:

PTR_TO_INT pointer1, pointer2, pointer3; // All are pointers.

Example:

int _tmain(int argc, _TCHAR* argv[])
{
    typedef int* PTR_MYINT;
    PTR_TO_INT xyz, abc;
    int* xyz1, abc1;

    xyz = NULL;
    abc = xyz; // Valid, as both are pointers

    abc1 = xyz1; // Invalid, as abc1 is not pointer
    return 0;
}

Upvotes: 3

Views: 615

Answers (4)

Bathsheba
Bathsheba

Reputation: 234665

In a similar way to the associativity of the dereference operator * being from right to left, the * when being used to specifier a type binds strictly to the right, and not the left token.

So it's associated with the variable name, rather than the type specifier.

Hence you need to write int * pointer1, * pointer2, * pointer3; with spacing according to your personal taste.

Effectively the typedef circumvents this associativity.

Upvotes: 5

too honest for this site
too honest for this site

Reputation: 12263

That is no "convention", but required by the syntax. The * binds to the right token (here: pointer1, not the left (here: int). This is the reason, "convention" is to write int *ip actually (as you write it when you dereference the pointer lateron to get the object it points to).

So

int *ip, i;

Are two variables: a pointer to int (ip) and an int (i).

If you need two pointers:

int *ip1, *ip2;

But it is often recommended for documentation purpose to have two lines with a comment:

int *ip1;   // the first pointer
int *ip2;   // points to the next element

Here the base-type is int. If you have a typedef

typedef int *IntPtr;

The defined type is a pointers to int already, so if you use that as the base-type for a declaration:

IntPtr ip1, ip2;

You get two pointers, because of the base-type as for the example above.

Warning: Such typedefs visually (i.e. to the programmer, not the compiler) hide the underlying pointer semantics. This is not only dangerous, but also missleading to the reader, as you always have to be aware of this. You should not do this in general. There are few exceptions, but they are for special use-cases only.


Note: Another way to see

int *ip;

is: *ip is of type int (object-type view).

Upvotes: 10

Tony Delroy
Tony Delroy

Reputation: 106086

But when we want to declare multiple pointers, why do we need to affix * to each of them?

int* pointer1, pointer2, pointer3; // Only first is pointer. Rest are integers

It's ultimately a quirky decision made when C was first written, which was probably motivated by the convenience and concision of being able to create both variables of some type, and pointers to such variables, in the same line of code.

int x, *p_x = &x;

When you're writing code that uses a lot of variables, fairly evenly mixed between pointers and non-pointers, that concision and convenience benefit can add up. Like many things in C, the programmer has the option to be extremely terse, and different programmers might have differing views on whether that's good or bad.

With a typedef, you're explicitly creating a particular alias for a type, and you may not even want the user of the typedef to know whether it's ultimately a pointer or not. For example:

typedef ...something... Handle;
Handle h = awesome_library_init();
awesome_library_finito(h);  // never knew if handle was int, struct*...
                            // may differ on e.g. Linux vs Windows

When client programmer are thereby encouraged to perceive the type as some opaque by-value type, it would be confusing if...

Handle h1, h2;

...didn't create two identical variables of the same type.

Upvotes: 4

fjellfly
fjellfly

Reputation: 388

typedef binds the * to the int (like in math when you put brakets around something).

Upvotes: -3

Related Questions