Разработчики языка решили сделать фигурные скобки в следующих сценариях необязательными:
if (a)
b
while (a)
b
...
Почему в функциях так же не разрешено?
int add(int a, int b)
return a + b;
Разработчики языка решили сделать фигурные скобки в следующих сценариях необязательными:
if (a)
b
while (a)
b
...
Почему в функциях так же не разрешено?
int add(int a, int b)
return a + b;
Я уверен, что это испортит грамматику. Например, не было бы никакой разницы между этим определением пустой функции...
void empty()
{
;
}
... и объявление этой функции:
void empty();
Я не уверен, что они "выбрали" это. Скорее, способность исключать фигурные скобки для if, while, for и т.д. Возникает как естественное следствие того, как они задавали грамматику. Граммер запрещает его для функций, вероятно, из-за деклараций функций старого стиля.
Не существует фиксированного ключевого слова, связанного с определениями функций. С if
/else
/for
/while
/switch
существует одно такое ключевое слово, которое знаменует начало структуры логического управления.
Даже если контекст позволяет нам понять, как получилось, что int some_name (some_expression) some_other_expressions;
является функцией - в практике программирования (хотя и недвусмысленно) требуется много отступления, чтобы убедиться, что впереди в токене изменяет это из объявления функции на что-то еще.
Парсер языка программирования может быть классифицирован по его подходу к разбору, либо он принимает текущий токен в списке токенов, и проверяет, подтверждает ли следующий токен "это есть" или "это функция", или требуется (2-3-6?) и подтверждает, что "это может быть функция", "теперь, когда я вижу пятый токен, это, безусловно, функция", или он использует обратный трассировку с переменным перспективным подходом, который идет как далеко вперед в списке токенов, так как нужно, чтобы убедиться, что конструкция, которую мы изучаем, не что-то еще.
Если бы я размышлял, я бы сказал, что это потому, что функция обычно содержит более одного оператора, тогда как оператор if или while часто содержит только одно утверждение. Кроме того, он оказался дальновидным, поскольку в С++, позволяющем исключить {}, приведет к двусмысленности в функциях-членах. Например:
struct s
{
void f() const int i; //does const refer to int i or the function?
}
Кудрявые фигурные скобки не являются необязательными компонентами управляющих операторов "if" и "if-else". Грамматическое производство для оператора управления if if позволяет одному нетерминальному символу следовать выражению. Грамматическое производство для оператора управления "if-else" позволяет одному нетерминальному символу следовать выражению и одному нетерминальному символу, чтобы следовать за символом терминала "else". Имя этого нетерминального символа - <statement> .
В контексте структур управления (контрольные утверждения a.k.a.) фигурные фигурные скобки принадлежат языковому нетерминальному символу, известному как < составной оператор > (иногда называемый <block> ). Нетерминальный символ < составной отчет > появляется в правой части <statement> грамматическое производство, поэтому фигурные скобки можно использовать с управляющими операциями if и else (т.е. составной оператор является).
<statement> ::= <if-then-statement> |
<if-then-else-statement> |
<for-statement> |
<do-while-statement> |
...
<compound-statement>
<statement-list> ::= <statement> | <statement-list> <statement>
<if-then-statement> ::= "if" "(" <expression> ")" <statement>
<if-then-else statement> ::= "if" "(" <expression> ")" <statement> 'else' <statement>
<compound-statement> ::= "{" <statement-list> "}"
Что касается объявлений функций, то < составной оператор > нетерминальный символ является последним нетерминальным символом в правой части декларации функции > грамматическое производство.
P.S. Все нетерминальные символы - грамматические произведения. Все грамматические произведения сводятся к одному или нескольким нетерминальным и/или терминальным символам. Символы терминала - это языковые ключевые слова.