Почему прототип требуется даже без какого-либо объявления класса? - PullRequest
4 голосов
/ 20 ноября 2011

Если я просто сделаю это: Ex1:

#include <iostream>

int main()
{
    //try to call doSomething function
    doSomething();
}

void doSomething()
{
    std::cout << "Call me now!" << std::endl;
}

Я получаю ошибку компиляции! Потому что компиляция не знает, что такое doSomething.

Но если я поменяю позицию doSomething на первое место, программа успешно скомпилируется. Ex2:

#include <iostream>

void doSomething()
{
    std::cout << "Call me now!" << std::endl;
}

int main()
{
    //try to call doSomething function
    doSomething();
}

Я могу объявить прототип так: Пример 3:

#include <iostream>

void doSomething(void);

int main()
{
    //try to call doSomething function
    doSomething();
}

void doSomething()
{
    std::cout << "Call me now!" << std::endl;
}

Но почему первый пример не работает? Почему мне даже нужно сначала объявить прототип или вызвать функции и, наконец, функцию main?

Спасибо!

Ответы [ 3 ]

6 голосов
/ 20 ноября 2011

Вы не можете вызывать функцию, если компилятор не увидел ни определения, ни объявления, во-первых, просто.Прототип или фактическое определение должны появиться перед вызовом.

1 голос
/ 20 ноября 2011

Это наследие от C. C - это однопроходной язык, который означает, что он должен делать все, читая файл только один раз.Чтобы вызвать функцию без предварительного объявления / прототипа, потребуется прочитать файл дважды;Первый раз, чтобы найти все сигнатуры функций и второй раз, чтобы фактически скомпилировать.

C ++ сохранил это требование для функций, которые были частью C, таких как свободные функции и глобальные переменные.Однако классы являются новыми для C ++, и не было необходимости придерживаться старого способа ведения дел.Таким образом, в рамках одного определения класса используется многопроходная компиляция.Вот почему вы можете сделать это:

class MyClass {
    void foo() {bar();}
    void bar() {}
};

Но вы не можете делать то, что перечислили в своем вопросе.

1 голос
/ 20 ноября 2011

Поскольку компилятор не видел doSomething до того, как его использовали.

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

...