Gotcha #20: Migrating Type-Qualifiers
There are no constant or volatile arrays, so type-qualifiers (const or volatile) applied to an array will migrate to an appropriate position within the type:
typedef int A[12];
extern const A ca; // array of 12 const ints
typedef int *AP[12][12];
volatile AP vm; // 2-D array of volatile pointers to int
volatile int *vm2[12][12]; // 2-D array of pointers to volatile int
This makes sense, since an array is really just a kind of literal pointer to its elements. It has no associated storage that could be constant or volatile, so the qualifiers are applied to its elements. Be warned, however: compilers often implement this incorrectly in more complex cases. For example, the type of vm above is often (erroneously) determined to be the same as that of vm2.
Things are a bit loopier with respect to function declarators. In the past, the behavior of common C++ implementations was to allow the same migration for function declarations:
typedef int FUN( char * );
typedef const FUN PF; // earlier: function that returns const int
// now: illegal
The standard now says that a type-qualifier can be applied to a function declarator in a "top-level" typedef and that typedef may be used only to declare a non-static member function:
typedef int MF() const;
MF nonmemfunc; // error!
class C {
MF memfunc; // OK.
};
It's probably best to avoid this usage. Current compilers don't always implement it correctly, and it's confusing to human readers as well.
|