Postfix Operators

The postfix operators have the highest precedence (the tightest binding) in expression evaluation.

Syntax

postfix-expression :
primary-expression
postfix-expression [ expression ]
postfix-expression ( argument-expression-list opt )
postfix-expression . identifier
postfix-expression –> identifier
postfix-expression ++
postfix-expression ––
postfix-expression :> expression /* Microsoft-specific */

Operators in this precedence level are the array subscripts, function calls, structure and union members, and postfix increment and decrement operators.

One-Dimensional Arrays

A postfix expression followed by an expression in square brackets ([ ]) is a subscripted representation of an element of an array object. A subscript expression represents the value at the address that is expression positions beyond postfix-expression when expressed as

postfix-expression[ expression]

Usually, the value represented by postfix-expression is a pointer value, such as an array identifier, and expression is an integral value. However, all that is required syntactically is that one of the expressions be of pointer type and the other be of integral type. Thus the integral value could be in the postfix-expression position and the pointer value could be in the brackets in the expression, or “subscript,” position. For example, this code is legal:

int sum, *ptr, a[10];

int main()

{

ptr = a;

sum = 4[ptr];

}

Subscript expressions are generally used to refer to array elements, but you can apply a subscript to any pointer. Whatever the order of values, expression must be enclosed in brackets ([ ]).

The subscript expression is evaluated by adding the integral value to the pointer value, then applying the indirection operator (*) to the result. (See “Indirection and Address-of Operators” for a discussion of the indirection operator.) In effect, for a one-dimensional array, the following four expressions are equivalent, assuming that a is a pointer and b is an integer:

a[b]

*(a + b)

*(b + a)

b[a]

According to the conversion rules for the addition operator (given in “Additive Operators”), the integral value is converted to an address offset by multiplying it by the length of the type addressed by the pointer.

For example, suppose the identifier line refers to an array of int values. The following procedure is used to evaluate the subscript expression line [ i ]:

1.The integer value i is multiplied by the number of bytes defined as the length of an int item. The converted value of i represents i int positions.

2.This converted value is added to the original pointer value ( line ) to yield an address that is offset i int positions from line.

3.The indirection operator is applied to the new address. The result is the value of the array element at that position (intuitively, line [ i ]).

The subscript expression line[0] represents the value of the first element of line, since the offset from the address represented by line is 0. Similarly, an expression such as line[5] refers to the element offset five positions from line, or the sixth element of the array.

Multidimensional Arrays

A subscript expression can also have multiple subscripts, as follows:

expression1 [expression2] [expression3]...

Subscript expressions associate from left to right. The leftmost subscript expression, expression1[expression2], is evaluated first. The address that results from adding expression1 and expression2 forms a pointer expression; then expression3 is added to this pointer expression to form a new pointer expression, and so on until the last subscript expression has been added. The indirection operator (*) is applied after the last subscripted expression is evaluated, unless the final pointer value addresses an array type (see examples below).

Expressions with multiple subscripts refer to elements of “multidimensional arrays.” A multidimensional array is an array whose elements are arrays. For example, the first element of a three-dimensional array is an array with two dimensions.

For the following examples, an array named prop is declared with three elements, each of which is a 4-by-6 array of int values.

int prop[3][4][6];

int i, *ip, (*ipp)[6];

A reference to the prop array looks like this:

i = prop[0][0][1];

The example above shows how to refer to the second individual int element of prop. Arrays are stored by row, so the last subscript varies most quickly; the expression prop[0][0][2] refers to the next (third) element of the array, and so on.

i = prop[2][1][3];

This statement is a more complex reference to an individual element of prop. The expression is evaluated as follows:

1.The first subscript, 2, is multiplied by the size of a 4-by-6 int array and added to the pointer value prop. The result points to the third 4-by-6 array of prop.

2.The second subscript, 1, is multiplied by the size of the 6-element int array and added to the address represented by prop[2].

3.Each element of the 6-element array is an int value, so the final subscript, 3, is multiplied by the size of an int before it is added to prop[2][1]. The resulting pointer addresses the fourth element of the 6-element array.

4.The indirection operator is applied to the pointer value. The result is the int element at that address.

These next two examples show cases where the indirection operator is not applied.

ip = prop[2][1];

ipp = prop[2];

In the first of these statements, the expression prop[2][1] is a valid reference to the three-dimensional array prop; it refers to a 6-element array (declared above). Since the pointer value addresses an array, the indirection operator is not applied.

Similarly, the result of the expression prop[2] in the statement ipp = prop[2]; is a pointer value addressing a two-dimensional array.

Function Calls

A “function call” is an expression that includes the name of the function being called or the value of a function pointer and, optionally, the arguments being passed to the function.

Syntax

postfix-expression :
postfix-expression ( argument-expression-list opt )

argument-expression-list :
assignment-expression
argument-expression-list
, assignment-expression

The postfix-expression must evaluate to a function address (for example, a function identifier or the value of a function pointer), and argument-expression-list is a list of expressions (separated by commas) whose values (the “arguments”) are passed to the function. The argument-expression-list argument can be empty.

A function-call expression has the value and type of the function's return value. A function cannot return an object of array type. If the function's return type is void (that is, the function has been declared never to return a value), the function-call expression also has void type. (See “Function Calls” for more information.)

Structure and Union Members

A “member-selection expression” refers to members of structures and unions. Such an expression has the value and type of the selected member.

Syntax

postfix-expression . identifier postfix-expression –> identifier

This list describes the two forms of the member-selection expressions:

1.In the first form, postfix-expression represents a value of struct or union type, and identifier names a member of the specified structure or union. The value of the operation is that of identifier and is an l-value if postfix-expression is an l-value. See “L-Value and R-Value Expressions” for more information.

2.In the second form, postfix-expression represents a pointer to a structure or union, and identifier names a member of the specified structure or union. The value is that of identifier and is an l-value.

The two forms of member-selection expressions have similar effects.

In fact, an expression involving the member-selection operator (–>) is a shorthand version of an expression using the period (.) if the expression before the period consists of the indirection operator (*) applied to a pointer value. Therefore,

expression –> identifier

is equivalent to

(*expression) . identifier

when expression is a pointer value.

The following examples refer to this structure declaration. See topic for information about the indirection operator (*) used in these examples.

struct pair

{

int a;

int b;

struct pair *sp;

} item, list[10];

A member-selection expression for the item structure looks like this:

item.sp = &item;

In the example above, the address of the item structure is assigned to the sp member of the structure. This means that item contains a pointer to itself.

(item.sp)–>a = 24;

In this example, the pointer expression item.sp is used with the member-selection operator (–>) to assign a value to the member a.

list[8].b = 12;

This statement shows how to select an individual structure member from an array of structures.

Postfix Increment and Decrement Operators

Operands of the postfix increment and decrement operators are scalar types that are modifiable l-values.

Syntax

postfix-expression :
postfix-expression ++
postfix-expression ––

The result of the postfix increment or decrement operation is the value of the operand. After the result is obtained, the value of the operand is incremented (or decremented). The following code illustrates the postfix increment operator.

if( var++ > 0 )

*p++ = *q++;

In this example, the variable var is compared to 0, then incremented. If var was positive before being incremented, the next statement is executed. First, the value of the object pointed to by q is assigned to the object pointed to by p. Then, q and p are incremented.> (base operator);described>

Base Operator (Microsoft Specific)

The base operator (:>) is a Microsoft extension added to support based addressing. The base operator combines a memory segment address with an address that can be dereferenced with the indirection (*) operator. It has the form> (base operator);described>

segvar :> offset

The segvar can be any expression that evaluates to a valid memory segment address. You can use a variable or expression of type __segment, or create your own segments using the __segname operator. The offset can be a pointer with the form

type __based( void ) *

or any 16-bit expression.

You can use the base operator to create a pointer that can address any memory location. See “Based Pointers” for more information.

32-Bit Specific

The base operator is not supported for 32-bit targets.¨