ptr attribute
The [ptr] attribute designates a pointer as a full pointer.
pointer_default(ptr)
typedef [ ptr [ , type-attribute-list ] ] type-specifier declarator-list;
typedef [ struct | union ]
{
[ ptr [ , field-attribute-list ] ] type-specifier declarator-list;
...
}
[ ptr [ , function-attribute-list ] ] type-specifier ptr-decl function-name(
[ [ parameter-attribute-list ] ] type-specifier [standard-declarator]
, ...);
[[ [ function-attribute-list ] ]] type-specifier [[ptr-decl]] function-name(
[ ptr [[ , parameter-attribute-list ]] ] type-specifier [[standard-declarator]]
, ...);
-
type-attribute-list
-
Specifies one or more attributes that apply to the type. Valid type attributes include [handle], [switch_type], [transmit_as]; the pointer attribute [ref], [unique, or [ptr]; and the usage attributes [context_handle], [string], and [ignore]. Separate multiple attributes with commas.
-
type-specifier
-
Specifies a base type, struct, union, or enum type or type identifier. An optional storage specification can precede type-specifier.
-
standard-declarator
-
Specifies a standard C declarator, such as an identifier, a pointer declarator, or an array declarator. For more information, see Array and Sized-Pointer Attributes, arrays, and Arrays and Pointers.
-
declarator-list
-
Specifies standard C declarators, such as identifiers, pointer declarators, and array declarators. For more information, see Array and Sized-Pointer Attributes, arrays, and Arrays and Pointers. The declarator-list consists of one or more declarators separated by commas. The parameter-name identifier in the function declarator is optional.
-
field-attribute-list
-
Specifies zero or more field attributes that apply to the structure or union member or function parameter. Valid field attributes include [first_is], [last_is], [length_is], [max_is], [size_is]; the usage attributes [string], [ignore], and [context_handle]; the pointer attribute [ref], [unique], or [ptr]; and the union attribute [switch_type]. Separate multiple field attributes with commas.
-
function-attribute-list
-
Specifies zero or more attributes that apply to the function. Valid function attributes are [callback], [local]; the pointer attribute [ref], [unique], or [ptr]; and the usage attributes [string], [ignore], and [context_handle].
-
ptr-decl
-
Specifies at least one pointer declarator to which the [ptr] attribute applies. A pointer declarator is the same as the pointer declarator used in C; it is constructed from the * designator, modifiers such as far, and the qualifier const.
-
function-name
-
Specifies the name of the remote procedure.
-
parameter-attribute-list
-
Consists of zero or more attributes appropriate for the specified parameter type. Parameter attributes can take the directional attributes in and out; the field attributes first_is, last_is, length_is, max_is, size_is, and switch_type; the pointer attribute ref, unique, or [ptr]; and the usage attributes context_handle and string. The usage attribute ignore cannot be used as a parameter attribute. Separate multiple attributes with commas.
The full pointer designated by the [ptr] attribute approaches the full functionality of the C-language pointer. The full pointer can have the value NULL and can change during the call from NULL to non-NULL. Storage pointed to by full pointers can be reached by other names in the application supporting aliasing and cycles. This functionality requires more overhead during a remote procedure call to identify the data referred to by the pointer, determine whether the value is NULL, and to discover if two pointers point to the same data.
Use full pointers for:
- Remote return values.
- Double pointers, when the size of an output parameter is not known.
- NULL pointers.
Full (and unique) pointers cannot be used to describe the size of an array or union because these pointers can have the value NULL. This restriction by MIDL prevents an error that can result when a NULL value is used as the size.
Reference and unique pointers are assumed to cause no aliasing of data. A directed graph obtained by starting from a unique or reference pointer and following only unique or reference pointers contains neither reconvergence nor cycles.
To avoid aliasing, all pointer values should be obtained from an input pointer of the same class of pointer. If more than one pointer points to the same memory location, all such pointers must be full pointers.
In some cases, full and unique pointers can be mixed. A full pointer can be assigned the value of a unique pointer, as long as the assignment does not violate the restrictions on changing the value of a unique pointer. However, when you assign a unique pointer the value of a full pointer, you may cause aliasing.
Mixing full and unique pointers can cause aliasing, as demonstrated in the following example:
typedef struct
{
[ptr] short * pdata; // full pointer
} GRAPH_NODE_TYPE;
typedef struct
{
[unique] graph_node * left; // unique pointer
[unique] graph_node * right; // unique pointer
} TREE_NODE_TYPE;
// application code:
short a = 5;
TREE_NODE_TYPE * t;
GRAPH_NODE_TYPE g, h;
g.pdata = h.pdata = &a;
t->left = &g;
t->right = &h;
// t->left->pdata == t->right->pdata == &a
Although "t->left" and "t->right" point to unique memory locations, "t->left->pdata" and "t->right->pdata" are aliased. For this reason, aliasing-support algorithms must follow all pointers (including unique and reference pointers) that may eventually reach a full pointer.
pointer_default(ptr)
typedef [ptr, string] unsigned char * MY_STRING_TYPE;
[ptr] char * MyFunction([in, out, unique] long * plNumber);