Почему функции должны быть объявлены до их использования? - PullRequest
18 голосов
/ 21 января 2011

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

Можно утверждать, что объявление функций перед их использованием, безусловно, является хорошим стилем, но мне интересно, есть ли какая-либо другая причина, почему это обязательно в C ++?

Редактировать - пример для иллюстрации: Предположим, вам нужны функции, которые встроены в заголовочный файл. Эти две функции вызывают друг друга (возможно, это рекурсивный обход дерева, где нечетные и четные слои дерева обрабатываются по-разному). Единственный способ решить эту проблему - сделать предварительное объявление одной из функций перед другой.

Более распространенный пример (хотя с классами, а не функциями) - это классы с конструкторами и фабриками private. Фабрике необходимо знать класс, чтобы создавать его экземпляры, а классу необходимо знать фабрику для объявления friend.

Если это требование издревле, почему оно не было снято в какой-то момент? Это не сломало бы существующий код, не так ли?

Ответы [ 11 ]

0 голосов
/ 29 января 2011

Тем не менее, вы можете использовать функцию до того, как она будет объявлена ​​иногда (если быть точным в формулировке: "before" соответствует порядку, в котором читается исходный код программы) - внутри класса!:

class A {
public:
  static void foo(void) {
    bar();
  }
private:
  static void bar(void) {
    return;
  }
};

int main() {
  A::foo();
  return 0;
}

(В соответствии с моими тестами изменение класса на пространство имен не работает.)

Это, вероятно, потому, что компилятор фактически помещает определения функций-членов внутри класса сразу после объявления класса, как кто-то указал на это в ответах.

Тот же подход может быть применен ко всему исходному файлу: сначала удалите все, кроме объявления, затем обработайте все отложенное. (Либо двухпроходный компилятор, либо достаточно большой объем памяти для хранения отложенного исходного кода.)

Ха-ха! Таким образом, они подумали, что весь исходный файл будет слишком большим для хранения в памяти, , но один класс с определениями функций не будет : они могут позволить сидеть целому классу в памяти и подождите, пока объявление не будет отфильтровано (или сделайте второй проход для исходного кода классов)!

...