декларация функции не является прототипом
у меня есть библиотека, которую я создал,
mylib.c:
#include <mylib.h>
int
testlib() {
printf("Hello worldn");
return (0);
}
mylib.h:
#include <stdio.h>
extern int testlib();
в моей программе я попытался вызвать эту библиотечную функцию:
myprogram.c:
#include <mylib.h>
int
main (int argc, char *argv[]) {
testlib();
return (0);
}
когда я пытаюсь скомпилировать эту программу, я получаю следующую ошибку:
In file included from myprogram.c:1
mylib.h:2 warning: function declaration isn't a prototype
Я: gcc (GCC) 3.4.5 20051201 (Red Hat 3.4.5-2)
мой вопрос в том, как правильно объявить функцию прототип?
3 ответов:
В C
int foo()иint foo(void)разные функции.int foo()принимает произвольное количество аргументов, в то время какint foo(void)принимает 0 аргументов. В C++ они означают одно и то же. Я предлагаю вам использоватьvoidпоследовательно, когда вы не имеете в виду никаких аргументов.если у вас есть переменная
a,extern int a;- это способ сказать компилятору, чтоa- это символ, который может присутствовать в другой единице перевода (компилятор C говорит для исходного файла), не разрешайте его до времени ссылки. С другой стороны, символы, которые являются именами функций, так или иначе разрешаются во время ссылки. Значение спецификатора класса хранения для функции (extern,static) влияет только на его видимость иexternпо умолчанию, так чтоexternна самом деле не нужно.Я предлагаю убрать
extern, это посторонние и, как правило, опускают.
быстрый ответ: изменить
int testlib()доint testlib(void), чтобы указать, что функция не принимает аргументов.A прототип по определению является объявлением функции, которое определяет тип(ы) аргумента (ов) функции.
объявление функции не-прототипа как
int foo();-это объявление старого стиля, в котором не указывается количество или типы аргументов. (До стандарта ANSI C 1989 года это была единственная функция декларация доступна на этом языке.) Вы можете вызвать такую функцию с любым произвольным числом аргументов, и компилятор не обязан жаловаться - но если вызов не соответствует определение ваша программа имеет неопределенное поведение.
для функции, которая принимает один или несколько аргументов, можно указать тип каждого аргумента в декларации:
int bar(int x, double y);функции без аргументов являются частным случаем. Логически, пусто круглые скобки были бы хорошим способом указать этот аргумент, но этот синтаксис уже использовался для объявлений функций старого стиля, поэтому комитет ANSI C изобрел новый синтаксис с использованием
voidключевые слова:int foo(void); /* foo takes no arguments */функция определение (которая включает в себя код для того, что функция на самом деле) также предоставляет декларация. В вашем случае, у вас есть что-то похожее на:
int testlib() { /* code that implements testlib */ }это обеспечивает non-прототип декларация для
testlib. В качестве определения это говорит компилятору, чтоtestlibне имеет параметров, но в качестве объявления он только сообщает компилятору, чтоtestlibпринимает некоторое неопределенное, но фиксированное число и тип(ы) аргументов.если вы измените
()до(void)декларация становится прототипом.преимущество прототипа в том, что если вы случайно позвоните
testlibС одним или несколькими аргументами компилятор будет диагностировать ошибка.(C++ имеет несколько другие правила. В C++ нет объявлений функций старого стиля, а пустые скобки специально означают, что функция не принимает аргументов. C++ поддерживает
(void)синтаксис для согласованности с C. Но если вам специально не нужен ваш код для компиляции как C, так и c++, вы, вероятно, должны использовать()в C++ и(void)синтаксис в с.)
Comments