Альтернативная декларация

Я заметил, что добавляет ключевое слово class или struct к типу, который в противном случае должен был быть объявлен вперед. работает так, как если бы этот тип был объявлен вперед:

// struct Test; forward declaration commented

void* foo(struct Test* t) // C style function parameter - This works !
{
    return t; 
}

Я не знал об этом. Я задаюсь вопросом, является ли это стандартным С++ или расширением и является ли ключевое слово struct до того, как параметр работает как объявление вперед или другой механизм запускает.

Кроме того, после такого использования функция "next" может использовать тип без добавления каких-либо ключевых слов:

void* oof(Test* t);

Demo

Ответ 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