The "Specifier List" that precedes the declarator is made up of distinctive groups of keywords and people often mix them up because the language doesn't enforce a particular order. My preference is to put them in the following order (it makes reading declarations much more natural):
1. Storage class specifiers, if any: static, extern, auto, register, typedef;
2. Type qualifiers, if any: const, volatile, restrict;
3. Type modifiers, if any: signed, unsigned, short, long;
4. The type specifier: int, double, char, etc.
Following that rule would lead to (IMHO) more readable declarations like this:
It's not hard to understand why you can't declare this: Functions in C are always 'constant' as far as the compiler is concerned, it doesn't make sense to every[sic] try to change one (at least in this language).
However, the given example with the const after the parameter list is legal for a C++ member function, meaning that it is a function with no side-effects on its object (except possibly the fields declared mutable, but I digress...) --- and upon consideration, might be a useful optimisation hint if it weren't for the fact that compilers now work on dataflow and can figure such things out itself.
There is actually another "secret hidden type" possible, the "volatile function":
typedef volatile int foo(void);
volatile foo a;
but it doesn't seem to make much sense, except perhaps as a "do not ever inline this function" anti-optimisation hint.
That said, the utility of functions returning CV-qualified types (not CV-qualifier pointer types) is also questionable. What does it mean for a function to return a const or volatile int, as opposed to a regular non-CV int? In C, it doesn't make sense to modify the return value of a function or have it be modified.
1. Storage class specifiers, if any: static, extern, auto, register, typedef;
2. Type qualifiers, if any: const, volatile, restrict;
3. Type modifiers, if any: signed, unsigned, short, long;
4. The type specifier: int, double, char, etc.
Following that rule would lead to (IMHO) more readable declarations like this:
Instead of (an extreme example):