Люди используют такие имена, как struct _Node
, чтобы преднамеренно игнорировать правила, установленные в стандарте (или, чаще, потому что они не знают о правилах, установленных в стандарте).Грубо говоря, в стандарте говорится, что имена, начинающиеся с подчеркивания, в основном зарезервированы для «реализации», то есть компилятора и системных библиотек.См. C11 §7.1.3 Зарезервированные идентификаторы для получения подробной информации:
- Все идентификаторы, которые начинаются со знака подчеркивания и либо с заглавной буквы, либо другого подчеркивания, всегда зарезервированы для любогоuse.
- Все идентификаторы, которые начинаются с подчеркивания, всегда зарезервированы для использования в качестве идентификаторов с областью файла как в обычном пространстве, так и в пространстве имен тега.
Также обратите внимание §6.2.1 Области применения идентификаторов - выделение добавлено:
Идентификатор может обозначать объект;функция;тег или член структуры, объединения или перечисления;имя определения типа;название ярлыка;имя макроса;или параметр макроса.Один и тот же идентификатор может обозначать разные объекты в разных точках программы.Член перечисления называется константой перечисления. Имена макросов и параметры макросов здесь далее не рассматриваются, , поскольку до семантической фазы трансляции программ любые вхождения имен макросов в исходном файле заменяются последовательностями токенов предварительной обработки, которые составляют их макроопределения.
Обратите внимание, что POSIX также резервирует суффикс _t
- см. Среда компиляции .
Тем не менее, мыслительный процесс выглядит как "это имя не должно"не использовать много; ставьте префикс с подчеркиванием, чтобы не использовать его ".А также «я видел, как это используется в системных заголовках; я скопирую этот стиль», не понимая, что системные заголовки кодируются таким образом, чтобы избежать использования пространства имен, зарезервированного для обычных программистов, и использовать пространство имен, зарезервированное для реализации..
Ваше переписывание разумно;это то, что я обычно делаю.
Чтобы ответить на расширенный вопрос:
Не все знают, что теги структуры находятся в отдельном пространстве имен от обычных идентификаторов, поэтому они не знают, чтоtypedef struct Book Book;
является полностью безопасным и однозначным (первый Book
находится в пространстве имен тегов и должен предшествовать struct
; второй Book
находится в пространстве имен обычных идентификаторов и должен не ему предшествует struct
).
Кроме того, люди смотрят на системные заголовки и видят, что они делают, и думают, что им следует скопировать стиль там, не зная, что реализация имеет навязанные ей разные правила относительно того, что она делает.можно и нельзя использовать для имен.
Обратите внимание, что Стандарты кодирования ядра Linux препятствуют использованию typedefs для структурных типов;они требуют, чтобы вы использовали struct WhatEver
везде.У правила есть некоторые преимущества и недостатки - самосогласованность, вероятно, важнее, чем соглашение, которое вы используете.Это означает «идти в ногу с потоком» для существующего проекта, но это не имеет большого значения, каким образом вы делаете это в новом проекте, если вы последовательны.
Вы можететакже найдите прецедент для использования альтернативных имен для тегов структуры и соответствующих им имен typedef в священном писании - что означает «язык программирования Си» Кернигана и Ричи.(Интересно, что их примеры несколько изменились между первым изданием 1978 года и вторым изданием 1988 года.)
Второе издание:
typedef struct tnode *Treeptr;
typedef struct tnode {
…
Treeptr left;
Treeptr right;
} Treenode;
Первое издание:
typedef struct tnode {
…
struct tnode *left;
struct tnode *right;
} TREENODE, *TREEPTR;
Обратите внимание, что современный стиль имеет тенденцию избегать использования typedef для указателей.См. Это хорошая идея, чтобы печатать указатели? .