2014-11-27 2 views
0

Мой вопрос является продолжением этого: extern function during linkage?ехЬегп функция во время связи

теперь я пытался в file2.c:

extern int foo(void); 

и я назвал

foo(1,2,3); 

Теперь я получил ошибку компиляции, что слишком много аргументов в foo (1,2,3);

Почему это происходит? Мы просто сказали, что ехЬегп функция ищутся во время связи, и что на этом этапе нет соображения относительно параметров ...

+0

Да, вы сказали компилятору, что foo() является внешней функцией, а также ее прототипом является int foo (void). Достаточно для компилятора проверить его параметры. –

+1

Вся цель первого утверждения состоит в том, чтобы объявить прототип foo(). Это то же самое, что и #include файла заголовка, в котором объявлен foo(). Если вы опустите первую строку и вызовите foo (1,2,3), процесс компиляции завершится успешно, с предупреждением о неявном объявлении. – Adashi

+0

В исходном вопросе было также различное количество параметров в файлах file1.c и file2.c, и оно скомпилировано и связано .. В чем разница? – user1047069

ответ

2

extern функции ищутся во время связи, и что на этом этапе нет соображения относительно параметров.

Это точно. Однако вы получаете ошибку на этапе компиляции, а не на этапе сцепления. Вы пообещали компилятору, что есть функция foo, которая не принимает никаких параметров, а затем вы вызываете foo с тремя параметрами. Компилятор не принимает этого и сообщает об ошибке.

Проблема с параметрами игнорирования компоновщика будет заключаться в том, если вы отдельно скомпилировали foo с нулевыми параметрами и вызовом foo с несогласованным прототипом, который принимает три параметра. Это неопределенное поведение.

impl.c

void foo() {} 

main.c

void foo(int,int,int); 
int main(int argc, char *argv[]) { 
    foo(1, 2, 3); 
    return 0; 
} 

Если вы компилировать выше, ссылка будет, потому что вы обманули компилятор, дав ему неправильный прототип, и компоновщик делает не знаю ничего лучше.

0

, произнеся extern int foo(void);, вы сообщаете компилятору искать определение функции во время соединения. В этом процессе вы уже поставляете прототип функции [объявление] int foo(void);, где число параметров равно 0.

Но при использовании вы вызываете foo(1,2,3);, поэтому происходит ошибка компиляции.

Примечание: Если я не ошибаюсь, объявления функций по умолчанию extern.

Смежные вопросы