Каковы правила использования подчеркивания в идентификаторе C ++?

Посмотрите внимательно, сколько скобок имеет ваш массив. Я встретил пример, когда функция вернула ответ с дополнительной скобкой, например:

>>>approx
array([[[1192,  391]],
       [[1191,  409]],
       [[1209,  438]],
       [[1191,  409]]])

И это не сработало

>>> approx[1,1]
IndexError: index 1 is out of bounds for axis 1 with size 1

. Это может открыть скобки:

>>> approx[:,0]
array([[1192,  391],
       [1191,  409],
       [1209,  438],
       [1191,  409]])

Теперь можно использовать стандартную запись доступа к элементу:

>>> approx[:,0][1,1]
409
885
задан Machavity 25 February 2019 в 13:39
поделиться

5 ответов

Правила (который не изменился в C++ 11):

Из Стандарта C++ 2003 года:

17.4.3.1.2 Глобальных набора [lib.global.names]

Certain имен имен и функциональных подписей всегда резервируются к реализации:

  • Каждое имя, которое содержит двойное подчеркивание (__) или начинается с подчеркивания, сопровождаемого прописной буквой (2.11), резервируется к реализации для любого использования.
  • Каждое имя, которое начинается с подчеркивания, резервируется к реализации для использования в качестве имени в глобальном пространстве имен. <глоток> 165

<глоток> 165) Такие имена также резервируются в пространстве имен ::std (17.4.3.1).

, поскольку C++ основан на стандарте C (1.1/2, C++ 03), и C99 является нормативной ссылкой (1.2/1, C++ 03), они также применяются с 1999 C Стандарт:

7.1.3 Зарезервированных идентификатора

Каждый заголовок объявляет или определяет все идентификаторы, перечисленные в его связанном подпункте, и дополнительно объявляет или определяет идентификаторы, перечисленные в его связанном будущем подпункте направлений библиотеки и идентификаторах, которые всегда резервируются или для любого использования или для использования в качестве идентификаторов объема файла.

  • Все идентификаторы, которые начинаются с подчеркивания и или прописная буква или другое подчеркивание, всегда резервируются для любого использования.
  • Все идентификаторы, которые начинаются с подчеркивания, всегда резервируются для использования в качестве идентификаторов с объемом файла и в пробелах обычного и в имени тега.
  • Каждое макро-имя в любом из следующих подпунктов (включая будущие направления библиотеки) резервируется для использования, как определено, если какой-либо из его связанных заголовков включен; если явно не указано иначе (см. 7.1.4).
  • Все идентификаторы с внешней связью в любом из следующих подпунктов (включая будущие направления библиотеки) всегда резервируются для использования в качестве идентификаторов с внешней связью. <глоток> 154
  • Каждый идентификатор с объемом файла, перечисленным в любом из следующих подпунктов (включая будущие направления библиотеки), резервируется для использования в качестве макро-имени и в качестве идентификатора с объемом файла в том же пространстве имен, если какой-либо из его связанных заголовков включен.

Никакие другие идентификаторы не резервируются. Если программа объявляет или определяет идентификатор в контексте, в котором она резервируется (кроме, как позволено 7.1.4) или определяет зарезервированный идентификатор как макро-имя, поведение не определено.

, Если программа удаляет (с #undef) какое-либо макроопределение идентификатора в первой упомянутой выше группе, поведение не определено.

<глоток> 154) список зарезервированных идентификаторов с внешней связью включает errno, math_errhandling, setjmp, и va_end.

Другие ограничения могли бы применяться. Например, стандарт POSIX резервирует много идентификаторов, которые, вероятно, обнаружатся в нормальном коде:

  • Имена, начинающиеся с капитала E, следовали за цифрой или прописной буквой:
    • может использоваться для дополнительных имен кода ошибки.
  • Имена, которые начинаются или is или to сопровождаемый строчной буквой
    • , могут использоваться для дополнительного тестирования символа и функций преобразования.
  • Имена, которые начинаются LC_ сопровождаемый прописной буквой
    • , могут использоваться для дополнительных макросов, определяющих атрибуты локали.
  • Названия всех существующих функций математики, снабженных суффиксом [1 112] или l, резервируются
    • для соответствующих функций, которые воздействуют на и длинные двойные споры плавающие, соответственно.
  • Имена, которые начинаются SIG сопровождаемый прописной буквой, резервируются
    • для дополнительных имен сигнала.
  • Имена, которые начинаются SIG_ сопровождаемый прописной буквой, резервируются
    • для дополнительных действий сигнала.
  • Имена, начинающиеся str, mem, или wcs сопровождаемый строчной буквой, резервируются
    • для дополнительных строковых функций и функций массива.
  • Имена, начинающиеся PRI или SCN сопровождаемый любой строчной буквой или X, резервируются
    • для дополнительных макросов спецификатора формата
  • Имена, которые заканчиваются [1 122], резервируются
    • для дополнительных имен типов.

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

<час>

Лично я просто не запускаю идентификаторы с подчеркиваний. Новое дополнение к моему правилу: не используйте двойные подчеркивания нигде, который легок, поскольку я редко использую подчеркивание.

После проведения исследований в области этой статьи я больше не заканчиваю свои идентификаторы [1 123], поскольку это резервируется стандартом POSIX.

правило о любом идентификаторе, заканчивающемся [1 124], удивило меня много. Я думаю, что это - стандарт POSIX (не уверенный все же) поиск разъяснения и официальной главы и стиха. Это от GNU libtool руководство , перечисляя зарезервированные имена.

CesarB обеспечил следующую ссылку на POSIX 2004 зарезервированные символы и примечания, 'которыми много других зарезервированных префиксов и суффиксов... могут быть найдены там'. POSIX 2008 зарезервированные символы определяются здесь. Ограничения несколько более детальны, чем те выше.

807
ответ дан 24 revs, 13 users 35%Roger Pate 25 February 2019 в 13:39
поделиться

Что касается другой части вопроса, распространено поместить подчеркивание в конец из имени переменной для не столкновения с чем-либо внутренним.

я делаю это ровные внутренние классы и пространства имен, потому что я тогда только еще должен помнить одно правило (по сравнению с "в конце имени в глобальной области видимости, и начало имени везде").

23
ответ дан Max Lybbert 25 February 2019 в 13:39
поделиться

Да, подчеркивания могут использоваться где угодно в идентификаторе. Я полагаю, что правила: любой из a-z, A-Z, _ в первом символе и тех + 0-9 для следующих символов.

префиксы Подчеркивания распространены в коде C - одинарное подчеркивание означает, что "частные", и двойные подчеркивания обычно резервируются для использования компилятором.

3
ответ дан John Millikin 25 February 2019 в 13:39
поделиться

От MSDN:

Использование двух последовательных символов подчеркивания (__) в начале идентификатора или единственного начального символа подчеркивания, сопровождаемого прописной буквой, резервируется для реализаций C++ во всех объемах. Необходимо избегать использования одного начального символа подчеркивания, сопровождаемого строчной буквой для имен с объемом файла из-за возможных конфликтов с текущими или будущими зарезервированными идентификаторами.

Это означает, что можно использовать одинарное подчеркивание в качестве членского префикса переменной, пока это сопровождается строчной буквой.

Это, по-видимому, взято от раздела 17.4.3.1.2 из стандарта C++, но я не могу найти первоисточник для полного стандарта онлайн.

См. также этот вопрос .

35
ответ дан Community 25 February 2019 в 13:39
поделиться

Правила избежать коллизии имен находятся оба в стандарте C++ (см. книгу Stroustrup), и упомянул гуру C++ (Sutter, и т.д.).

Персональное правило

, поскольку я не хотел иметь дело со случаями и хотел простое правило, я разработал персональный то, которое и просто и корректно:

При именовании символа, Вы избежите коллизии с библиотеками компилятора/ОС/стандарта если Вы:

  • никогда не запускаются, символ с подчеркиванием
  • никогда не называют символ с двумя последовательными подчеркиваниями внутри.

, Конечно, помещая Ваш код в уникальное пространство имен помогает избежать коллизии, также (но не защитит от злых макросов)

Некоторые примеры

(я использую макросы, потому что они - более загрязняющие код из символов C/C++, но это могло быть что-либо от имени переменной до имени класса)

#define _WRONG
#define __WRONG_AGAIN
#define RIGHT_
#define WRONG__WRONG
#define RIGHT_RIGHT
#define RIGHT_x_RIGHT

Извлечения из C++ 0x проект

От n3242.pdf файл (я ожидаю, что заключительный стандартный текст будет подобен):

17.6.3.3.2 Глобальных набора [global.names]

Certain имен имен и функциональных подписей всегда резервируются к реализации:

— Каждое имя, которое содержит двойное подчеркивание _ _ или начинается с подчеркивания, сопровождаемого прописной буквой (2.12), резервируется к реализации для любого использования.

— Каждое имя, которое начинается с подчеркивания, резервируется к реализации для использования в качестве имени в глобальном пространстве имен.

, Но также и:

17.6.3.3.5 Пользовательских литеральных Литерала суффиксов [usrlit.suffix]

снабжают суффиксом идентификаторы, которые не запускаются с подчеркивания, резервируются для будущей стандартизации.

Этот последний пункт сбивает с толку, если Вы не полагаете, что имя, запускающееся с одного подчеркивания и сопровождаемый строчной буквой, было бы в порядке, если бы не определил в глобальном пространстве имен...

189
ответ дан paercebal 25 February 2019 в 13:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: