SEL> Или, так, но это не объясняет, почему для "do { ... } while(0)" нет
SEL> альтернативы. Если строить описательные конструкции на человеческом
SEL> языке, то операторы перехода, оператор выражения и оператор do
SEL> завершаются ";", составной оператор завершается "}", а остальные
SEL> операторы завершаются другим оператором.
Обратите внимание: после обычного compound statement не положено
ставить ';' - она может поменять смысл программы! А именно это
получается, если бы вместо X() поставить {Y,Z} без while(0). То есть
имея, например,
if (cond)
X();
else
XX();
в случае подстановки без while(0) получаем:
if (cond)
{Y;Z};
else
XX();
Это не распарсится правильно, потому что {Y;Z} сработает как условие
по then, затем встретится ';' и поиск ветки else будет закончен,
потому что грамматика для if-конструкции закончилась. Далее, если этот
else не к чему отнести, будет ошибка парсинга, а если есть к чему
снаружи - будет отнесено неправильно (и это ещё одна причина, почему
стили настаивают, что все хоть как-то сложные конструкции заключаются
в {}).
Зато при правильной подстановке получим
if (cond)
do {Y;Z;} while(0);
else
XX();
и таких проблем не будет.
SEL> Я в наречиях западных англосакских варваров слаб, но в ISO/IEC 9899:2011
SEL> есть место, практически без единого слова, которое и процитирую, см.
SEL> 6.8.3, 6.8.5 и 6.8.6:
Вот и проанализируйте его с точки зрения, когда в
SEL> (6.8.4) selection-statement:
SEL> if ( expression ) statement
SEL> if ( expression ) statement else statement
SEL> switch ( expression ) statement
окажется
if ( expression) statement statement else statement
Результат, думаю, очевиден.
Да, вот такую дрянь подсунули авторы синтаксиса Си и все его
последователи (включая Java, C# и ещё тысячи их). Вирт эту ловушку
заметил раньше и в Модуле потребовал обязательность блоковых скобок.
Ещё мне очень нравится вариант синтаксиса встроенных скриптов SIP
Express Router, в остальном C-подобный:
if (condition) { statement-list }
[ elsif (condition) { statement-list } ] ...
[ else { statement-list } ]
;
то есть ';' обязательна для завершения всей конструкции и не может
встретиться раньше. В этой схеме можно и сделать явный блок:
{ statement-list };
или, для ясности,
do { statement-list };
путаницы с do-while не возникнет.
--netch--