Чому люди так багато використовують __ (подвійне підкреслення) в C ++


93

Я переглядав якийсь код із відкритим кодом C ++ і помічав багато подвійних оцінок, коли вони використовувались у коді, головним чином на початку імен змінних.

return __CYGWIN__;

Просто цікаво, чи є для цього причина, чи це просто деякі стилі коду людей? Думаю, мені важко читати.


2
Чому важко читати? Він розроблений здебільшого як деліметр, як і цитати. Як я пам’ятаю, він в основному використовується для вбудованих констант.
Метью Шарлі

1
Ні, це не роздільник. Підкреслення використовуються для розрізнення імен, зарезервованих для реалізації, від імен, які може використовувати вихідний код користувачів. Користувачі можуть робити, #define FOO 1але не повинні, #define __FOO__ 1і тому реалізація може вільно використовувати ім'я __FOO__для власних макросів, змінних, функцій тощо
Джонатан

Я думаю, Метью мав на увазі, що це стилістично / візуально деліметр, а не функціонально. Що є цікавою гіпотезою, але неправильною, враховуючи те, що я раніше читав, і відповідь Джонатана.
JMI MADISON

Відповіді:


127

З програмування на C ++, правила та рекомендації :

Використання двох підкреслень (`__ ') в ідентифікаторах зарезервовано для внутрішнього використання компілятора відповідно до стандарту ANSI-C.

Підкреслення (`_ ') часто використовуються в іменах бібліотечних функцій (наприклад," _main "та" _exit "). Щоб уникнути зіткнень, не починайте ідентифікатор підкресленням.


1
Цей посібник виглядає так, ніби він був написаний до namespaceвведення.
cz

це також було з імперського коледжу Лондона, а не зі стандарту C ++; це може бути гарною пропозицією.
штукатурка

1
@cz Простори імен не мають значення. Заголовок системи може визначити ім'я макроса, яке починається з підкреслення, наприклад _main.
martinkunev

49

Якщо вони не відчувають, що вони є "частиною реалізації", тобто стандартними бібліотеками, тоді вони не повинні.

Правила є досить конкретними та дещо докладнішими, ніж пропонували деякі інші.

Всі ідентифікатори, які містять подвійне підкреслення або починаються з підкреслення, після якого йде велика літера, зарезервовані для використання реалізації в усіх сферах, тобто вони можуть бути використані для макросів.

Крім того, всі інші ідентифікатори, які починаються з підкреслення (тобто не слідують за іншим підкресленням або великою літерою), зарезервовані для реалізації в глобальному масштабі. Це означає, що ви можете використовувати ці ідентифікатори у власних просторах імен або у визначеннях класів.

Ось чому корпорація Майкрософт використовує імена функцій із символами нижнього підкреслення та з малими літерами для багатьох основних функцій бібліотеки середовища виконання, які не є частиною стандарту С ++. Ці імена функцій гарантовано не суперечать ні стандартним функціям C ++, ні функціям коду користувача.


1
У C ++ я бачу лише [lex.name] та для глобальних імен [global.names]. Чи можете ви дати посилання? спасибі
a.lasram

36

Згідно зі стандартом C ++, ідентифікатори, що починаються з одного підкреслення, зарезервовані для бібліотек. Ідентифікатори, що починаються з двох символів підкреслення, зарезервовані для постачальників компіляторів.


18
Більше того: ідентифікатори, що містять подвійне підкреслення в будь-якому місці в них , зарезервовані. 17.4.3.1.2
Стів Джессоп,

У C ++ я бачу лише [lex.name] та для глобальних імен [global.names]. Чи можете ви дати посилання? спасибі
a.lasram

10

Попередні коментарі є правильними. __Symbol__зазвичай є магічним маркером, який надає ваш корисний постачальник компілятора (або препроцесора). Мабуть, найбільш широко використовуваними з них є __FILE__і __LINE__, які розширені препроцесором С для позначення поточного імені файлу та номера рядка. Це зручно, коли ви хочете реєструвати якийсь збій твердження програми, включаючи текстове розташування помилки.


8

Це те, що ви не повинні робити в "звичайному" коді. Це гарантує, що компілятори та системні бібліотеки можуть визначати символи, які не будуть стикатися з вашими.


4

Подвійне підкреслення зарезервовано для реалізації

Відповідь, яка отримала найбільшу кількість голосів, посилається на Програмування на C ++: Правила та рекомендації :

"Використання двох підкреслень (` __ ') в ідентифікаторах зарезервовано для внутрішнього використання компілятора відповідно до стандарту ANSI-C. "

Однак, прочитавши кілька стандартів C ++ та C, я не зміг знайти жодної згадки про підкреслення, обмежені лише внутрішнім використанням компілятора. Стандарти є більш загальними, що передбачає подвійне підкреслення для впровадження .

C ++

У C ++ (поточний робочий проект, доступний у 2019-5-26) зазначено lex.name:

  • Кожен ідентифікатор, що містить подвійне підкреслення __ або починається з підкреслення, за яким слідує велика літера, зарезервовано для реалізації для будь-якого використання.
  • Кожен ідентифікатор, який починається з підкреслення, зарезервований для реалізації для використання як імені в глобальному просторі імен.

C.

Незважаючи на те, що це питання стосується С ++, я процитував відповідні розділи зі стандартів С 99 і 17:

C99, розділ 7.1.3

  • Всі ідентифікатори, які починаються на підкреслення та велику літеру або іншу підкреслення, завжди зарезервовані для будь-якого використання.
  • Всі ідентифікатори, які починаються з підкреслення, завжди зарезервовані для використання в якості ідентифікаторів з обсягом файлів як у звичайному, так і в просторі імен тегів.

С17 говорить те саме, що і С99.

Що таке реалізація ?

Для C / C ++ реалізація вільно посилається на набір ресурсів, необхідних для створення виконуваного файлу з вихідних файлів користувача. Це включає:

  • препроцесор
  • компілятор
  • лінкер
  • стандартна бібліотека

Приклади реалізацій

У Вікіпедії згадується ряд різних реалізацій C ++ . (відсутнє прив'язне посилання, ctrl + f "реалізація")

Ось приклад реалізації C / C ++ Digital Mars, який резервує деякі ключові слова для їх особливості.


3

На додаток до бібліотек, про які відгукувались багато інших людей, Деякі люди також називають макроси або значення #define для використання з препроцесором. Це полегшило б роботу і, можливо, дозволило б обробляти помилки в старих компіляторах.

Як і інші згадані, це допомагає запобігти зіткненню імен та допомагає розмежувати між бібліотечними змінними та вашими власними.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.