На всякий случай небольшая выдержка из стандарта.
Определение функции:
Цитата:8.3.5 Functions
...
D1 ( parameter-declaration-clause ) cv-qualifier-seqopt exception-specificationopt
Определение "parameter-declaration-clause":
Цитата:parameter-declaration-clause:
parameter-declaration-listopt ...opt
parameter-declaration-list , ...
parameter-declaration-list:
parameter-declaration
parameter-declaration-list , parameter-declaration
parameter-declaration:
decl-specifier-seq declarator
decl-specifier-seq declarator = assignment-expression
decl-specifier-seq abstract-declaratoropt
decl-specifier-seq abstract-declaratoropt = assignment-expression
По поводу "decl-specifier-seq":
Цитата:As a general rule, at most one type-specifier is allowed in the complete decl-specifier-seq of a declaration.
The only exceptions to this rule are the following:
— const or volatile can be combined with any other type-specifier. However, redundant cvqualifiers
are prohibited except when introduced through the use of typedefs (7.1.3) or template type
arguments (14.3), in which case the redundant cv-qualifiers are ignored.
— signed or unsigned can be combined with char, long, short, or int.
— short or long can be combined with int.
— long can be combined with double.
Соответственно, получаем, что использование выражений:
Type1_t Type2_t ParamName
или
Type1_t Type2_t
противоречит стандарту, т.к. они не являются валидными объявлениями.