Ответ 1
Это законно, но, вероятно, не очень хорошая идея.
От [basic.scope.pdecl]/6:
[...] - для уточненного типа-спецификатора формы
идентификатор ключа класса
если специфицированный спецификатор типа используется в предложении decl-specifier-seq или параметре-декларации функция, определенная в области пространства имен, идентификатор объявляется как имя класса в пространстве имен, содержит объявление [...]
Например:
namespace mine {
struct T* foo(struct S *);
// ^^^^^^^^^---------------- decl-specifier-seq
// ^^^^^^^^^^--- parameter-declaration-clause
}
Это вводит T
и S
как имена классов и foo
как имя функции в namespace mine
.
Обратите внимание, что поведение отличается от C; имя структуры действует только в пределах области действия.
6.2.1 Области идентификаторов
4 - [...] Если спецификатор декларатора или типа, который объявляет идентификатор [...] в списке объявлений параметров в определение функции, идентификатор имеет область действия блока, которая заканчивается в конце связанный блок. Если появляется декларатор или спецификатор типа, объявляющий идентификатор в списке объявлений параметров в прототипе функции (не является частью функции определение), идентификатор имеет область прототипа функции, которая заканчивается в конце Объявление функции.
gcc дает соответствующее предупреждение для этого использования в коде C:
a.c:3:18: warning: ‘struct Test’ declared inside parameter list
void* foo(struct Test* t)
^
a.c:3:18: warning: its scope is only this definition or declaration, which is probably not what you want