У меня вот возник такой вопрос после просматривания сообщений в
этом форуме.
Очень часто в коде, посылаемом в сообщении, встречаются точки с запятыми после
закрывающих фигурных скобок тела функции. Типа:
void foo()
{
}; <----
И опять же, очень часто в ответах идут замечания об необходимости/желательности
убрать эти точки с запятыми из кода.
Почему так? Это только стилистические предпочтения или действительно есть ситуации когда
это становится критическим?
WBR,
Влад Волосюк
P.S. Я очень часто сам ставлю эти точки запятые. Особенно после того, как потратил
довольно значительное время на поиски ошибки в коде, связанной (как потом выяснилось) с
отсутствием точки запятой после объявления класса.
Здравствуйте deviv, Вы писали:
D>Почему так? Это только стилистические предпочтения или действительно есть ситуации когда D>это становится критическим?
Гм. Не разу не встречался со случаем когда это "критично".
Скорее всего некоторые сишные "пюристы" пытались тебя "уесь" хотя бы этим аргументом — за неимением лучших аргументов — наверно таким образом они пытались почесать свое самолюбие...
Правда стОит запомнить — если после конца болка функции точка с запятой не нужна, то после определения класса она просто необходима...
____________________
God obviously didn't debug, hasn't done any maintenance, and no documentation can be found. Truly amateur work.
Здравствуйте deviv, Вы писали:
D>У меня вот возник такой вопрос после просматривания сообщений в D>этом форуме.
D>Очень часто в коде, посылаемом в сообщении, встречаются точки с запятыми после D>закрывающих фигурных скобок тела функции. Типа:
D>
D>void foo()
D>{
D>}; <----
D>
D>И опять же, очень часто в ответах идут замечания об необходимости/желательности D>убрать эти точки с запятыми из кода.
D>Почему так? Это только стилистические предпочтения или действительно есть ситуации когда D>это становится критическим?
Точка с запятой после финальной закрывающей скобки определения функции является ситаксической ошибкой и в С, ив С++.
Вполне возможно, что некоторые компиляторы смотрят на эту ошибку сквозь пальцы. Тем не менее это синтаксическая ошибка и стать "критической" она может в любой момент — с выходом новой версии компилятора, при смене компилятора или просто при изменении какой-нибудь опции компиляции.
Здравствуйте Андрей Тарасевич, Вы писали:
АТ>Точка с запятой после финальной закрывающей скобки определения функции является ситаксической ошибкой и в С, ив С++.
АТ>Вполне возможно, что некоторые компиляторы смотрят на эту ошибку сквозь пальцы. Тем не менее это синтаксическая ошибка и стать "критической" она может в любой момент — с выходом новой версии компилятора, при смене компилятора или просто при изменении какой-нибудь опции компиляции.
А если вот так:
class Bar {
void foo()
{
std::cout << "foo\n";
};// <----
};
Считается ли точка с запятой ошибкой в этом случае?
Здравствуйте MaximE, Вы писали:
ME>Здравствуйте Андрей Тарасевич, Вы писали:
АТ>>Точка с запятой после финальной закрывающей скобки определения функции является ситаксической ошибкой и в С, ив С++.
АТ>>Вполне возможно, что некоторые компиляторы смотрят на эту ошибку сквозь пальцы. Тем не менее это синтаксическая ошибка и стать "критической" она может в любой момент — с выходом новой версии компилятора, при смене компилятора или просто при изменении какой-нибудь опции компиляции.
ME>А если вот так:
ME>
ME>Считается ли точка с запятой ошибкой в этом случае?
Нет, в этом случае ошибки нет. Так что мое превоначальное утверждение надо уточнить: после финальной закрывающей скобки определения метода класса, сделанного внутри определения самого класса, точку с запятой можно ставить, а можно и не ставить. В остальных случаях точка с запятой после определения фнукции — синтаксическя ошибка.
Здравствуйте Андрей Тарасевич, Вы писали:
АТ>Точка с запятой после финальной закрывающей скобки определения функции является ситаксической ошибкой и в С, ив С++.
Гм... Не буду рвать трусы на жопе, но VC6SP3 (это то что у меня есть дома) на нижеприведенный код дал зеленый свет.
int main()
{
return 0;
};
...однако пока воздержусь и от поедания печени поверженного врага...
А к завтрашнему от вас хотелось бы увидеть где же в станадртах такое сказано...
Хотя печень — штука вкусная....
____________________
God obviously didn't debug, hasn't done any maintenance, and no documentation can be found. Truly amateur work.
Здравствуйте TepMuHyc, Вы писали:
TMH>Гм... Не буду рвать трусы на жопе, но VC6SP3 (это то что у меня есть дома) на нижеприведенный код дал зеленый свет. TMH>
TMH>int main()
TMH>{
TMH> return 0;
TMH>};
TMH>
TMH>...однако пока воздержусь и от поедания печени поверженного врага...
Ну VC6, я думаю, уже давно никто в качестве эталона соответсвия стандарту языка не использует,
TMH>А к завтрашнему от вас хотелось бы увидеть где же в станадртах такое сказано...
Явно не сказано. Есть грамматика языка, которая и описывает подобные ситуации.
В разделе 9.2 приводится фрагмент грамматики, описывающий определение методов класса внутри определения класса
member-declaration :
function-definition ;opt
В разделе 8.4 приводится фрагмент грамматики, описывающий определения функций
Как видишь опциональная точка с запятой в первом случае разрешена не потому, что она допускается общей грамматикой определения функции, а потому, что она явно разрешена именно в грамматике определения метода внутри определения класса. Во втором случае ("отдельностоящее" определение функции) никакой точки с запятой нет и в помине и никаких лазеек для нее не оставлено.
Если тебе нравится проверять такие вещи путем экспериментов с компиляторами — попробуй Comeau Online Compiler.
Здравствуйте deviv, Вы писали:
D>Очень часто в коде, посылаемом в сообщении, встречаются точки с запятыми после D>закрывающих фигурных скобок тела функции. Типа:
D>
D>void foo()
D>{
D>}; <----
D>
D>И опять же, очень часто в ответах идут замечания об необходимости/желательности D>убрать эти точки с запятыми из кода.
1) В таком стиле обычно пишут люди
которые не очень давно пересели с pascal на C/C++,
там как раз требуется эта ";"
2) Так иногда пишуть люди которые активно пользуются
вставкой.копированием при написании программ
т.е. я написал класс
class A
{
public:
void C(много параметров);
void D(много параметров);
}
Теперь мне надо написать реализацию C и D, т.к. у меня
уже есть правильно
Любая проблема дизайна может быть решена введением дополнительного абстрактного слоя, за исключением проблемы слишком большого количества дополнительных абстрактных слоев
Здравствуйте Anatolix, Вы писали:
A>2) Так иногда пишуть люди которые активно пользуются A>вставкой/копированием при написании программ A>т.е. человек написал класс
A>
A>class A
A>{
A>public:
A> void C(много параметров);
A> void D(много параметров);
A>}
A>
A>Теперь человеку надо написать реализацию C и D, т.к. у него A>уже есть правильно описанная функция, и он ее копирует из A>.h в .cpp и вставляет A:: и {} при этом иногда забывает
удалить ;
Любая проблема дизайна может быть решена введением дополнительного абстрактного слоя, за исключением проблемы слишком большого количества дополнительных абстрактных слоев
Здравствуйте TepMuHyc, Вы писали:
TMH>Здравствуйте Андрей Тарасевич, Вы писали:
АТ>>Точка с запятой после финальной закрывающей скобки определения функции является ситаксической ошибкой и в С, ив С++.
TMH>Гм... Не буду рвать трусы на жопе, но VC6SP3 (это то что у меня есть дома) на нижеприведенный код дал зеленый свет.
А также компилятор gcc и с++ под Unix несчитают это ошибкой
и спокойно компилируют следующий фрагмент кода
int main()
{
return 0;
};
TMH>...однако пока воздержусь и от поедания печени поверженного врага...
TMH>А к завтрашнему от вас хотелось бы увидеть где же в станадртах такое сказано... TMH>Хотя печень — штука вкусная....
Здравствуйте Slyder, Вы писали:
S>А также компилятор gcc и с++ под Unix несчитают это ошибкой S>и спокойно компилируют следующий фрагмент кода S>
S>int main()
S>{
S> return 0;
S>};
S>
По-видимому, создатели этих компиляторов сочли данный вопрос непринципиальным. И gcc 2.95, и VC6, например, разрешают помещать лишние ';' в вне каких-либо statement в любых количествах (хоть ';;;;;;;;;;;;;'). Не знаю, как именно они их трактуют — то ли как пустой statement, то ли как пустой декларатор. В лбом случае, ни легальным C, ни легальным С++ это не является.
Здравствуйте Slyder, Вы писали:
S>А также компилятор gcc и с++ под Unix несчитают это ошибкой S>и спокойно компилируют следующий фрагмент кода S>
S>int main()
S>{
S> return 0;
S>};
S>
Вообще, мало ли что компиляторы соглашаются компилировать, компиляторы это такие же программы, которые пишут обычные программисты. Поэтому слова, что что-то чем-то компилируется, в общем-то, ровным счетом ничего не значат, о правильности компилируемого текста.
Что же касается лишних ‘;’ – то это нелегально по Стандарту, но почти все реальные компиляторы смотрят на это сквозь пальцы. Так как программисты привыкли их писать, а для компилятора ничего не стоит их проигнорировать.
Здравствуйте Андрей Тарасевич, Вы писали:
TMH>>А к завтрашнему от вас хотелось бы увидеть где же в станадртах такое сказано...
АТ>Явно не сказано. Есть грамматика языка, которая и описывает подобные ситуации.
АТ>В разделе 9.2 приводится фрагмент грамматики, описывающий определение методов класса внутри определения класса
АТ>
АТ>(Первый фрагмент, кстати, ссылается на второй.)
АТ>Как видишь опциональная точка с запятой в первом случае разрешена не потому, что она допускается общей грамматикой определения функции, а потому, что она явно разрешена именно в грамматике определения метода внутри определения класса. Во втором случае ("отдельностоящее" определение функции) никакой точки с запятой нет и в помине и никаких лазеек для нее не оставлено.
На самом деле этого еще недостаточно для того, чтобы показать, что точка с запятой не модет быть поставлена после "отдельностоящего" определения функции. Вполне может быть, что эта точка с запятой никакого отношения к функции не имеет, а является, например, совершенно самостоятельной синтаксической конструкцией — пустой декларацией. Для того, чтобы выяснить, разрешаются ли такие декларации в С++, надо рассмотреть структуру единицы компиляции с самого верха и убедиться, что и там не оставлено никаких лазеек для этой точки с запятой.
Единица компиляции в С++, согласно 3.5/1 и 7/1, является последовательностью деклараций
Вот она, наша точка с запятой! Как видно из грамматики, обе части 'simple-declaration' являются опциональными. Если окажется, что они могут отсутствовать одновременно, то получится, что декларация в С++ может быть пустой, т.е. состоять просто из точки с запятой. Это даст нам право писать вот такие программы
void foo()
{
}
;;;;;;;;;;;;; // <- последовательность пустых декларацийvoid bar()
{
}; // <- то же самое - пустая декларация после определения функции
Однако, если почитать немного дальше, что в 7/3 выяснится следующая деталь: вторая часть 'simple-declaration' (т.е. 'init-declarator-list') может отсутствовать только в том случае, если вся декларация объявляет class или enum (т.е. в первой части — 'decl-specifier-seq' — должен присутствовать либо class-specifier, либо enum-specifier). Это требование полностью исключает возможность того, что 'simple-declaration' может быть пустой. Таким образом эта ветка грамматики С++ не позволяет нам протащить в С++ программу лишние точки с запятой. Каких-либо других возможностей сделать это в грамматике С++ нет. Отсюда мораль — точка с запятой после "отдельностоящего" определения функции (как и "пустая декларация") в С++ программе является синтаксической ошибкой.
Я еще не заглядывал в грамматику С. Думаю, там результат будет таким же.