У меня есть библиотека, которую я создал,
mylib.c:
#include <mylib.h>
int
testlib() {
printf("Hello world\n");
return (0);
}
mylib.h:
#include <stdio.h>
extern int testlib();
В моей программе я попытался вызвать эту библиотечную функцию:
myprogram.c:
#include <mylib.h>
int
main (int argc, char *argv[]) {
testlib();
return (0);
}
Когда я пытаюсь скомпилировать эту программу, я получаю следующую ошибку:
В файле из myprogram.c: 1 mylib.h: 2 предупреждение: объявление функции не является прототипом
Я использую: gcc (GCC) 3.4.5 20051201 (Red Hat 3.4.5-2)
У меня вопрос, как правильно объявить прототип функции?
Ответы:
В Си
int foo()
иint foo(void)
есть разные функции.int foo()
принимает произвольное количество аргументов, в то время какint foo(void)
принимает 0 аргументов. В C ++ они означают одно и то же. Я предлагаю вам использоватьvoid
последовательно, когда вы имеете в виду без аргументов.Если у вас есть переменная
a
,extern int a;
это способ сообщить компилятору, чтоa
это символ, который может присутствовать в другом модуле перевода (компилятор C говорит об исходном файле), не разрешайте его до времени ссылки. С другой стороны, символы, которые являются именами функций, в любом случае разрешаются во время соединения. Значение спецификатора класса хранения для функции (extern
,static
) влияет только на ее видимость иextern
является значением по умолчанию, поэтомуextern
фактически не является необходимым.Я предлагаю удалить
extern
, это постороннее и обычно опускается.источник
(void)
в C, чтобы указать, что функция не принимает аргументов. В C ++, если вам не нужен ваш код для компиляции как в C, так и в C ++, просто используйте()
.Быстрый ответ: измените
int testlib()
на,int testlib(void)
чтобы указать, что функция не принимает аргументов.Прототип , по определению , объявление функции , которая определяет тип (ы) аргумент функции (ы).
Объявление функции без прототипа, например
это объявление старого стиля, в котором не указывается количество или типы аргументов. (До стандарта ANSI C 1989 года это было единственное объявление функции, доступное на языке.) Вы можете вызывать такую функцию с любым произвольным числом аргументов, и компилятор не должен жаловаться - но если вызов несовместим с определением , ваша программа имеет неопределенное поведение.
Для функции, которая принимает один или несколько аргументов, вы можете указать тип каждого аргумента в объявлении:
Функции без аргументов являются особым случаем. Логически, пустые скобки были бы хорошим способом указать, что аргумент, но этот синтаксис уже используется для объявлений функций старого стиля, поэтому комитет ANSI C изобрел новый синтаксис, используя
void
ключевое слово:Функция определения (которая включает в себя код для того, что на самом деле делает функция) также предоставляет декларацию . В вашем случае у вас есть что-то похожее на:
Это обеспечивает объявление не-прототипа для
testlib
. Как определение, это говорит компилятору, что уtestlib
него нет параметров, но как объявление, это только говорит компилятору, которыйtestlib
принимает неуказанное, но фиксированное число и тип (ы) аргументов.При изменении
()
в(void)
декларации становится прототипом.Преимущество прототипа состоит в том, что если вы случайно вызовете
testlib
один или несколько аргументов, компилятор диагностирует ошибку.(C ++ имеет немного другие правила. C ++ не имеет объявлений функций старого стиля, и пустые скобки специально означают, что функция не принимает аргументов. C ++ поддерживает
(void)
синтаксис для согласованности с C. Но если вам не нужен ваш код для компиляции как C и C ++, вы, вероятно, должны использовать()
в C ++ и(void)
синтаксис в C.)источник
Пытаться:
источник