Читая разные C++-кодовые базы, можно заметить хаос в code style'ах. Qt использует к camelCase, стандартная библиотека и Boost используют snake_case, где-то любят PascalCase. Дополнительно хочу отметить нейминг приватных членов класса. Есть несколько часто встречающихся стилей:
_member // Подозрительно! m_member member_
Но у C++ в этом плане есть пара подводных мин. Некоторые имена зарезервированы стандартом для реализации: компилятора, стандартной библиотеки, рантайма и прочих приколов.
Что говорит стандарт
В разделе [lex.name] (пункты 4.1 — 4.2) черновика стандарта C++ указано, что часть идентификаторов зарезервирована для реализации и не должна использоваться пользовательским кодом. В частности, идентификаторы с двойным подчёркиванием __ где угодно, а также идентификаторы, начинающиеся с подчёркивания и заглавной буквы, зарезервированы для реализации для любого использования. Отдельно сказано, что идентификаторы, начинающиеся с подчёркивания, зарезервированы для реализации как имена в глобальном пространстве имён. Диагностика при этом не обязательна.
Если коротко:
class Widget { private: int _size; // обычно допустимо: член класса, _ + lowercase int _Toggle; // плохо: _ + uppercase, зарезервировано int __cache; // плохо: содержит __, зарезервировано int size_; // обычно допустимо int size__x; // плохо: содержит __, зарезервировано }; int _global; // плохо: имя в глобальном namespace, начинается с _
Значит ли это, что название переменной _size в классе запрещено?
Нет. И это как раз место, где легко ошибиться.
class Widget { private: int _size; };
Такое имя обычно не нарушает правило стандарта, потому что это не глобальное имя, но проблема в другом: стиль с leading underscore легко превращается в минное поле.
Сегодня мы назвали переменную:
int _size;
Завтра кто-то добавил акроним:
int _URL;
И всё: _ + uppercase — зарезервировано для реализации, ровно также как и данное имя:
int __cache; // Или такое: int cache__line;
То есть имя переменной _member — не всегда нарушение. Но это стиль, который стоит слишком близко к границе, за которой начинается уже не вопрос вкуса, а нарушение правил языка.
Почему это может отстрелить вам ногу?
Потому что стандартная библиотека и компилятоор имеют право использовать зарезервированные идентификаторы для своих нужд. Например, внутри стандартной библиотеки, системных заголовков, ABI-слоя, внутренних макросов и прочей инфраструктуры.
Raymond Chen в статье Microsoft DevBlogs отдельно показывает те же категории именований переменных. Он также отмечает, что популярная конвенция с подчёркиванием перед приватными членами легко ломается, если к имени переменной в начале добавить нижнее подчеркивание, а далее продолжить с заглавной буквы.
И компилятор не обязан вас спасать. Стандарт прямо говорит: no diagnostic required. То есть можно написать код, который формально нарушает правило, а компилятор спокойно промолчит.
Для проверки можно использовать clang-tidy с bugprone-reserved-identifier: он как раз ищет использование идентификаторов, зарезервированных для реализации, включая Name, глобальные name и __ внутри C++-идентификаторов.
А как делают большие проекты?
Google C++ Style Guide использует snake_case для переменных, а для data members классов — trailing underscore: table_name_. При этом поля struct называются как обычные переменные, без суффикса.
Chromium в целом следует Google C++ Style Guide, если в собственном гайде не указаны исключения.
LLVM использует CamelCase-подход: переменные должны быть существительными и начинаться с заглавной буквы, функции — с маленькой; для STL-подобных классов допускаются имена в стиле стандартной библиотеки.
C++ Core Guidelines не пытаются узаконить единственный стиль. Там прямо признаётся, что naming/layout часто субъективны, но всё равно предлагаются дефолтные правила: использовать единый стиль, предпочитать underscore_style, а ALL_CAPS оставлять только для макросов.
Boost рекомендует имена в нижнем регистре с подчёркиваниями, а макросы — в верхнем регистре с префиксом BOOST_.
Mozilla использует систему префиксов: m для member, s для static member, g для global, a для argument, k для constant; макросы начинаются с MOZ_.
Qt Creator использует m_ для members, но делает исключения для d и q pointers, связанных с d-pointer/pimpl-паттерном. Сам d-pointer в Qt используется для сокрытия деталей реализации и сохранения бинарной совместимости библиотек.
Что с _member в реальных проектах?
Такой стиль существует. Иногда он встречается даже в крупных и известных кодовых базах. Например, в Telegram Desktop можно встретить private members с leading underscore вроде lastUpdate, sets, _owner и так далее.
Заключение
В С++ полноподводных камней и нейминг переменных одно из них. Лично мне больше нравится STL или Boost‑like нейминг, то есть снейк кейс и придерживаюсь того, что нижнее подчеркивание и далее название переменной — плохая практика. А что думаете вы?
Комментарии (16)

slinkinone
25.05.2026 10:11_в начале имени члена класса весьма удобен - при написании и чтении когда сразу с первого символа названия переменной понимаешь что это не аргумент и не локальная переменная.
Explorus
25.05.2026 10:11Я бы очень хотел, чтобы кто-нибудь провел полноценное и непредвзятое исследование на тему удобного/быстрого восприятия/чтения этих самых подчеркиваний в именах. А до этих пор любые утверждения, что что-то удобно или неудобно являются исключительно субъективными. Как мне кажется, восприятие переменной происходит целиком (т.е. целым словом, мы не читаем по буквам), и мнение, что взгляд сперва целляется за подчеркивание выглядит несколько сомнительным. То есть таким же образом можно утверждать, что глаз цепляется за подчеркивание в конце имени после его прочтения и сразу понимаешь, что перед тобой член класса. В большинстве стайлгайдов префиксные подчеркивания запрещены из-за возможных случайных ошибок (тонкости стандарта порой даже мидлы не знают).

slinkinone
25.05.2026 10:11Так и есть - это субъективный-объективизм)
Здесь нет правильно или неправильного ответа (пока это не ломает сборку компилятором) и определяется мэинтейнером проекта.

shved4 Автор
25.05.2026 10:11Я согласен, что это полный субъективизм, но все же я склоняюсь к тому, что такой стиль больше плохая практика.

domix32
25.05.2026 10:11Ну, вы вроде читаете код слева направо и понимание о принадлежности к классу закономерно наступает при лидирующем подчерке. Если вы из тех немногих, кто имеет фотографическую память и воспринимает блоки текста как единое целое наверняка завершающий подчерк было бы настолько же проще отличать.
Другая проблема - подсказки от редакторов. Когда у вас в коде всплывают
varиvar_, то член класса будет обычно отсортирован вторым по порядку и можно случайно выбрать не то что ожидалось и потом тратить время чтобы найти косяк в методе._varв этом плане полезнее, т.к. сразу видно намерение.Что-нибудь типа
Foo::Foo(int myvar) : myvar_(myvar) {} // поди не промахнись с выбором подсказки Foo::do_something(int myvar) { int data = process(); // много строчек кода // // myvar = data; // как скоро заметишь что myvar_ не поменялся // без статанализа - только при запуске } Bar::Bar(int myvar) : _myvar(myvar) {} // при вводе подчерка покажет всех членов класса Bar::do_something(int myvar) { int data = process(); // много строчек кода // // _myvar = data; // переменная механически отлична от локальных переменных }что глаз цепляется за подчеркивание в конце имени после его прочтения и сразу понимаешь
возможно для тех у кого хорошее зрение это работает. Для тех кто зрением послабже может быть сродни шуму, особенно если непрописываемые знаки включены на отображение.

domix32
25.05.2026 10:11Раньше использовали
m_иg_для непубличных членов, сейчас перешёл на просто одинарное подчеркивание в членах класса. Двойное не использую, чтобы не зацепить никакие built in.
monah_tuk
25.05.2026 10:11Аналогично пробую. Ещё иногда пытаюсь в snake_case, но не хватает визуального отличия в некоторых местах в отсутствии подсветки. Но для себя писал стайл гайд, основа camelCase и m_

john_crew
25.05.2026 10:11Кто как хочет, кому как удобно, и как договорятся, на мой взгляд.
Глобальная функция / статичный метод класса - с заглавной буквы (GetInstance, Init).
Метод класса, локальная переменная - с прописной (getValue, setOption, process).
Константа или макрос - всё заглавными (MAX_SIZE, PI, APP_ID).
Раньше я использовал _ вначале имен переменных/членов класса, мне было удобно в редакторе просматривать что у меня есть, но как-то незаметно для себя переехал на постфиксный стиль))

oficsu
25.05.2026 10:11Завтра кто-то добавил акроним:
_URLПисать акроним капсом – это всё ещё плохая идея безотносительно подчёркивания, поскольку имя переменной капсом пересекается с общепринятым неймингом констант или макросов
И возможно, что на практике такой нейминг в процессе ревью нанесёт даже больший ущерб, чем ifndr из-за подчёркивания

shved4 Автор
25.05.2026 10:11Я такое не раз встречал в коде старших разработчиков (5+ лет в индустрии)...

old2ev
25.05.2026 10:11В основном как в команде определено, так и нужно код оформлять, но лично для себя я использую следующие правила:
PascalCase - всё что является типом данных (class, struct, enum, и т.д.)
camelCase - всё что может вызываться (функции, функторы в том числе лямблы) и первое слово всегда глагол: set…, get…, is…, load… и т.д.
snake_case - данные (переменные, поля классов, аргументы функций), при чём не зависимо от константности.
Как по мне венгерская нотация, в любом её проявлении(в т.ч. _*, __*, m_*, g_* и т.д.) давно изжила себя - на дворе далеко не 72-й год, для этих же целей в любой уважающей себя IDE давно присутствует такая замечательная штука как статический анализатор, который в случае необходимости подробно покажет и расскажет что, где и как хранится, зачем для этого городить какие-то избыточные правила нейминга, заставляя всю команду разработки их соблюдать. Тем более не вижу смысла в C++ использовать префиксы библиотек, как это делает Qt (QObject, QCoreApplication, QSettings и т.д.), для этих целей вообще-то в языке пространства имён есть.
Explorus
В каком стайлгайде Вы видели использование подчеркивания в начале имени? В конце имени подчеркиваине для того, чтобы показать, что это член класса (Google С++ Styleguide). Да, встречается код, где в начале имени подчеркивание добавляют из тех же соображений, но распространенной практикой это назвать сложно.
shved4 Автор
В распространенных стайл-гайдах (гугл, мозилла, ллвм) я такого не видел, но такой стиль достаточно распространен в разных закрытых конторках, галерках. Лично в моей организации есть соглашение о стиле кода, где такой нейминг приватных членов является "правильным" и рекомендуется к использованию, а остальные стили считаются неверными...
shved4 Автор
Такой стиль встречается в телеграм десктоп))