Действительно ли использование ведущих подчеркиваний вызывает проблемы? - PullRequest
3 голосов
/ 03 апреля 2012

Стандарт C / C ++ резервирует все идентификаторы, которые либо ведут с подчеркиванием (плюс заглавная буква, если не в глобальном пространстве имен), либо содержат два или более смежных подчеркивания .Пример:

int _myGlobal;
namespace _mine
{
    void Im__outta__control() {}
    int _LivingDangerously;
}

Но что, если мне просто все равно?Что если я решу жить опасно и все равно использовать эти «зарезервированные» идентификаторы?Насколько опасно я буду жить?

Вы когда-нибудь видели проблему с компилятором или компоновщиком, возникающую из-за использования зарезервированных идентификаторов по коду пользователя?

Ответы ниже до сих пор составляют, "Зачем нарушать правила, если это может вызвать проблемы?"Но представьте, что у вас уже есть код, который нарушает правила.В какой момент издержки, связанные с нарушением правил, перевесят затраты на рефакторинг кода для соответствия?Или что, если программист разработал персональный стиль кодирования, который требовал диких подчеркиваний (например, возможно, из другого языка)?Предполагая, что изменение их стиля кодирования было для них более или менее болезненным, что могло бы побудить их преодолеть боль?

Или я мог бы задать тот же вопрос в обратном порядке.Что конкретно делают библиотеки C / C ++ с зарезервированными словами, от которых пользователь может упасть?Они объявляют глобалы, которые могут привести к конфликтам именФункции?Классы?Естественно, каждая библиотека отличается, но как в целом может проявиться это столкновение?

Я учу студентов-программистов, которые приходят ко мне с такими вопросами, и все, что я могу им сказать, это: «Это против правил."Это суеверный, махающий рукой ответ.Более того, за двадцать лет программирования на C ++ я никогда не видел ошибок компилятора или компоновщика, которые возникали в результате нарушения правил зарезервированных слов.

Хороший скептик, столкнувшись с каким-либо правилом, спрашивает: «Почему мне это нужно?»Итак: почему я должен заботиться?

Ответы [ 4 ]

3 голосов
/ 08 февраля 2013

Меня сейчас волнует, потому что я только что столкнулся с ошибкой с подчеркиванием, большой и старой кодовой базой, в основном предназначенной для Windows и скомпилированной с VS2005, но некоторые также кросс-скомпилированы для Linux. При анализе обновлений более нового gcc я перестраивал некоторые из них под cygwin только для простоты проверки синтаксиса. Я получил совершенно непонятные ошибки (для моего крошечного мозга) из строки вроде:

template< size_t _N = 0 > class CSomeForwardRef;

Это привело к ошибке вроде:

error: expected ‘>’ before numeric constant

Google при этой ошибке обнаружил https://svn.boost.org/trac/boost/ticket/2245 и https://svn.boost.org/trac/boost/ticket/7203, оба из которых намекали на то, что на пути может появиться шальная #define. Конечно же, проверка предварительно обработанного источника с помощью -E и поиск по пути включения выявили некоторые биты, связанные с .h (забудьте, какой), который определил _N. Позже в той же одиссеи я столкнулся с похожей проблемой с _L.

Редактировать: Не связано с битами, но связано с символами: /usr/include/ctype.h - вот некоторые примеры вместе с тем, как ctype.h использует их:

#define _L      02
#define _N      04
.
.
.
#define isalpha(__c)    (__ctype_lookup(__c)&(_U|_L))
#define isupper(__c)    ((__ctype_lookup(__c)&(_U|_L))==_U)
#define islower(__c)    ((__ctype_lookup(__c)&(_U|_L))==_L)
#define isdigit(__c)    (__ctype_lookup(__c)&_N)
#define isxdigit(__c)   (__ctype_lookup(__c)&(_X|_N))

Я буду сканировать источник на предмет всех подчеркнутых идентификаторов и отсеять с помощью переименования все те, которые мы создали по ошибке ...

Jon

2 голосов
/ 03 апреля 2012

Насколько опасно я буду жить?
Достаточно опасно, чтобы сломать ваш код при следующем обновлении компилятора.

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

Так как у вопроса есть щепотка: "Это может быть неправильно, но насколько это может быть неправильно, и когда когда-либо это было неправильно" аромат, я думаю Мерфизакон довольно точно отвечает на это:

«Все, что может пойти не так, пойдет не так (если вы меньше всего этого ожидаете)». [#]

[#] (, ) - это мое изобретение, а не Мэрфи.

1 голос
/ 03 апреля 2012

Результаты могут отличаться в зависимости от конкретного компилятора, которого вы будете использовать.Что касается «уровня опасности» - каждый раз, когда вы получаете ошибку - вам нужно будет задаться вопросом, происходит ли она от вашей реализованной логики или от того факта, что вы не используете стандарт.

Но это не таквсе ... допустим, кто-то говорит вам: "это совершенно безопасно!"Таким образом, вы можете сделать это без каких-либо проблем (только при условии…). Будет ли это переопределять ваше мышление, когда вы доберетесь до ошибки, или все же вы будете удивляться, если есть небольшая вероятность, что он ошибался?:)

Итак, вы понимаете, какой бы ответ вы ни получили, он никогда не будет хорошим.(что делает меня на самом деле, как ваш вопрос)

1 голос
/ 03 апреля 2012

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

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

Это не так уж и вероятно, но нет причин делать это.

...