[ Team LiB ] |
![]() ![]() |
Gotcha #18: Creative Declaration-Specifier OrderingAs far as the language is concerned, the ordering of declaration-specifiers is immaterial:
int const extern size = 1024; // legal, but weird
However, without a compelling reason to depart from convention, it's best to follow the de facto standard ordering of these specifiers: linkage-specifier, type-qualifier, type. extern const int size = 1024; // normal What's the type of ptr?
int const *ptr = &size;
Right. It's a pointer to a constant integer, but you wouldn't believe how many programmers read the declaration as constant pointer to integer:
int * const ptr2 = &size; // error!
These are two very different types, of course, since the first is allowed to refer to a constant integer, and the second isn't. Colloquially, many programmers refer to pointers to constant data as "const pointers." This is not a good idea, because it communicates the correct meaning (pointer to constant data) only to ignoramuses, and will mislead any competent C++ programmer who takes you at your word (a constant pointer to non-constant data). Admittedly, the standard library contains the concept of a const_iterator that is, unforgivably, an iterator that refers to constant elements; the iterator itself is not constant. (Just because the standards committee has a bad day doesn't mean you should emulate them.) Distinguish carefully between "pointer to const" and "constant pointer." (See Gotcha #31.) Because the order of declaration-specifiers is technically immaterial, a pointer to const can be declared in two different ways:
const int *pci1;
int const *pci2;
Some C++ experts recommend the second form of the declaration because, they claim, it's easier to read in more complex pointer declarations:
int const * const *pp1;
Placing the const qualifier last in the list of declaration-specifiers allows us to read the pointer modifiers in a declaration "backward"; that is, from right to left: pp1 is a pointer to a const pointer to a const int. The conventional arrangement doesn't allow such a simple rule: const int * const *pp2; // same type as pp1 However, it's not inordinately more complex than the previous arrangement, and C++ programmers who read and maintain code containing such elaborate declarations are probably capable of figuring them out. More important, pointers to pointers and similarly complex declarations are rare, especially in interfaces where they're more likely to be encountered by less experienced programmers. Typically, one finds them deep in the implementation of a facility. Simple pointers to constant are much more common, and it therefore makes sense to follow convention in order to avoid misunderstanding: const int *pci1; // correct: pointer to const ![]() |
[ Team LiB ] |
![]() ![]() |