С++: почему объявление функции разрешено внутри другой функции, но не определение функции?

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

Можем ли мы иметь функции внутри функций?

Принятый ответ говорит, что это НЕТ. Я попробовал и получил тот же результат.

Но когда я попытался скомпилировать приведенный ниже код (только объявление), он скомпилировался. Я не совсем уверен, почему это разрешено.

#include <iostream>
using namespace std;

int main(int argc, char* argv[])
{
    int a, *b, f(int c); //trying out multiple name declaration
    int f(int c);
}

person pasha    schedule 13.08.2018    source источник
comment
Итог - это разрешено, потому что стандарт С++ говорит, что это так. Кроме того, в современном C++ вы можете определять функции внутри других функций в виде лямбда-выражений.   -  person    schedule 13.08.2018
comment
@NeilButterworth, Да, согласен, но для этого должно быть какое-то приложение. Я просто хочу это знать.   -  person pasha    schedule 13.08.2018
comment
@pasha Нет, данная особенность грамматики не обязательно бесполезна. Это может быть просто безобидная ерунда.   -  person Caleth    schedule 13.08.2018
comment
это предварительная декларация.   -  person dan    schedule 13.08.2018
comment
Предварительное объявление @dan что? Я никогда не слышал, чтобы люди говорили форвардное объявление в отношении функций.   -  person SergeyA    schedule 13.08.2018
comment
Предварительное объявление @SergeyA - это просто объявление, которое не является определением. Это (прямое) объявление функции: int f(int c);   -  person eerorika    schedule 13.08.2018
comment
Я не уверен, есть ли для этого какая-то причина. Я не вижу возможности использовать эту функцию по какой-либо причине.   -  person SergeyA    schedule 13.08.2018
comment
@ user2079303, нет, это объявление функции. Не форвардное объявление, по крайней мере, это терминология, используемая в Стандарте. Насколько мне известно, термин упреждающее объявление используется только для неполных типов.   -  person SergeyA    schedule 13.08.2018
comment
@SergeyA, правда? Как насчет этой цитаты из стандарта template<> auto g(double); // OK, forward declaration with unknown return type. Конечно, это предварительное объявление шаблона функции, но имеет ли это значение? Насколько я знаю, стандарт на самом деле не определяет, что такое объявление forward, и это просто прилагательное, описывающее объявление, а не технический термин. Я ошибаюсь?   -  person eerorika    schedule 13.08.2018
comment
@user2079303 user2079303 Я думаю, возможно, ты прав. Похоже, стандарт не использует форвардное объявление в качестве нормативного термина. Похоже, говорят обыватели. Но все же я бы сказал, что на непрофессиональном языке объявление функции обычно называется просто объявлением, а объявление класса называется опережающим объявлением. Подтверждающие доказательства: google.com/search?q=forward+declaration+cppreference (это показывает, что ссылка cpp упоминает этот термин, когда речь идет о структурах) - и когда речь идет о функциях, объявление fwd исходит только из стандартного примера.   -  person SergeyA    schedule 13.08.2018
comment
Разное не то же самое.   -  person Pete Becker    schedule 13.08.2018
comment
FWIW, вы можете изменить и добавить аргументы по умолчанию для функции при их повторном объявлении, а новые значения по умолчанию действительны только в области действия нового объявления. Я сомневаюсь, что это причина этой функции, но чем больше вы знаете... ;)   -  person Holt    schedule 14.08.2018


Ответы (1)


С++: почему объявление функции разрешено внутри другой функции, но не определение функции?

Потому что стандарт говорит об этом (или не запрещает это явно). Примечание: то же самое относится к объявлению глобальных переменных в пределах блока.

Вы можете спросить, почему комитет по стандартам не запретил это. Не все обоснования для каждого правила, и особенно отсутствие гипотетических правил стандарта, задокументированы, но в этом случае я могу предположить.

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

Вы также можете спросить, почему в C разрешены объявления функций. Насколько мне известно, использование объявлений функций блочной области видимости в современном C сократилось, и это пережиток времен до стандартизации. Вероятно, мы можем продолжить языковое наследие до языка B. Я сам мало что знаю о B, но пример кода в википедии встречается иметь объявление функции области видимости блока.

person eerorika    schedule 13.08.2018
comment
Мое мнение о стандарте такое: если это разрешено, значит, для этого есть причина. Итак, я хотел это знать. Если вы говорите, что в стандарте существуют случайные вещи из прошлого, это для меня ново. - person pasha; 14.08.2018
comment
Причина — обратная совместимость. - person eerorika; 14.08.2018
comment
Имеет смысл. Но кто-то, должно быть, сказал что-то вроде: «Боже, почему мы поддерживаем материал языка B для С++ 17». - person pasha; 14.08.2018
comment
@pasha Я не думаю, что люди изучают языковые правила, думая, сколько у них давней истории, и решают, что нужно что-то делать, если они старые. C++ по-прежнему имеет много общего с B. - person eerorika; 14.08.2018