Declarators are the components of a declaration that specify names. Declarators can also modify basic type information to cause names to be functions or pointers to objects or functions. (Specifiers, discussed in Chapter 6, Declarations, convey properties such as type and storage class. Modifiers, discussed in this chapter and in Appendix B, Microsoft-Specific Modifiers, modify declarators.) Figure 7.1 shows a complete declaration of two names, szBuf
and strcpy
, and calls out the components of the declaration.
Figure 7.1 Specifiers, Modifiers, and Declarators
Microsoft Specific
Most Microsoft extended keywords can be used as modifiers to form derived types; they are not specifiers or declarators. (See Appendix B, Microsoft-Specific Modifiers.)
END Microsoft Specific
Syntax
declarator :
dname
ptr-operator declarator
declarator ( argument-declaration-list ) cv-mod-list
declarator [ constant-expressionopt ]
( declarator )
ptr-operator :
* cv-qualifier-listopt
& cv-qualifier-listopt
complete-class-name :: * cv-qualifier-listopt
cv-qualifier-list :
cv-qualifier cv-qualifier-listopt
cv-qualifier :
const
volatile
cv-mod-list :
cv-qualifier cv-mod-listopt
pmodel cv-mod-listopt
dname :
name
class-name
~ class-name
typedef-name
qualified-type-name
Declarators appear in the declaration syntax after an optional list of specifiers (decl-specifiers). These specifiers are discussed in Chapter 6, Declarations. A declaration can contain more than one declarator, but each declarator declares only one name. The following sample declaration shows how specifiers and declarators are combined to form a complete declaration:
const char *pch, ch;
In this preceding declaration, the keywords const and char make up the list of specifiers. Two declarators are listed: *pch
and ch
. The simplified syntax of a declaration, then, is the following, where const char
is the type and *pch
and ch
are the declarators:
type declarator1[, declarator2[...,declaratorn] ] ;
When the binding of elements in a declarator list does not yield the desired result, you can use parentheses for clarification. A better technique, however, is to use a typedef or a combination of parentheses and the typedef keyword. Consider declaring an array of pointers to functions. Each function must obey the same protocol so that the arguments and return values are known:
// Function returning type int that takes one
// argument of type char *.
typedef int (*PIFN)( char * );
// Declare an array of 7 pointers to functions
// returning int and taking one argument of type
// char *.
PIFN pifnDispatchArray[7];
The equivalent declaration can be written without the typedef declaration, but it is so complicated that the potential for error exceeds any benefits:
int ( *pifnDispatchArray[7] )( char * );