Почему при выполнении этой программы выдается ошибка "конфликтующего типа"?

В главе 1.9 K&R я экспериментировал с программой, представленной ниже. В частности, что было бы, если бы я убрал некоторые замедления функций.

Итак, я удалил строку №4. int getline (char line [], int maxline

И, насколько мне известно, программа полностью соответствует и функционирует должным образом.

Когда я удаляю строку №5. недействительная копия (char to [], char from []);

Программа выдает следующую ошибку:

yay.c: 37: 6: предупреждение: конфликтующие типы для ‘copy’ void copy (char to [], char from [])

yay.c: 15: 9: примечание: предыдущее неявное объявление «копии» было здесь копией (самой длинной строкой);

#include <stdio.h>
#define MAXLINE 1000

int getline(char line[], int maxline);
void copy(char to[], char from[]);

main()
{
    int len;
    int max;
    char line[MAXLINE];
    char longest[MAXLINE];

    max = 0;
    while ((len = getfatline(line, MAXLINE)) > 0)

        if (len > max) {
            max = len;
            copy(longest, line);
        }

    if (max > 0)
        printf("%s", longest);

return 0;
}


int getfatline(char s[], int lim)
{
    int c, i;

    for (i=0; i<lim-1 && (c=getchar()) !=EOF && c != '\n'; ++i)
        s[i] = c;

    if (c == '\n') {
        s[i] = c;
        ++i;
    }

    s[i] = '\0';
    return i;
}

void copy(char to[], char from[])
{

        int i;

        i = 0;

        while ((to[i] = from[i]) != '\0')
                ++i;
}

Может ли кто-нибудь мне это объяснить?


person Jaccob    schedule 19.01.2016    source источник


Ответы (3)


Согласно последнему стандарту C C11, каждая функция должна быть (по крайней мере) объявлена ​​до того, как она будет использована. Таким образом, компилятор будет знать сигнатуру функции.

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

  • Функция возвращает int
  • принимает любое количество параметров.

Позже, когда вы определите функцию, чтобы она имела тип возврата, отличный от int, это создаст конфликт.

Поэтому,

  • удаление прямого объявления getline() не приводит к ошибке.
  • удаление прямого объявления copy() вызывает ошибку, несоответствие возвращаемого типа.

Аналогично, main() больше не требуется, так как неявный int также был удален. Вы должны написать int main(void), по крайней мере, чтобы соответствовать стандарту.

person Sourav Ghosh    schedule 19.01.2016

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

void copy(char to[], char from[]);

Но если вы не предоставите прототип, тип возвращаемого значения функции по умолчанию принимается как int.


Это причина, по которой он работает для функции getfatline(), потому что его тип возвращаемого значения - int, когда вы используете его позже в коде, что совпадает с принятым по умолчанию при удалении прототипа.

Но когда вы удаляете прототип функции copy, тип возвращаемого значения по умолчанию устанавливается равным int, но ваше определение функции имеет тип возвращаемого значения void, именно здесь возникает конфликт, и это вызывает ошибку.

person Haris    schedule 19.01.2016

Getline фактически определен в заголовке stdio.h

ssize_t getline(char **lineptr, size_t *n, FILE *stream); 

следовательно, удаление вашей собственной реализации getline не вызовет ошибки. Вместо этого удаление другой функции вызовет ошибку, потому что такой функции не существует в stdio.h, но она определяется пользователем. Кстати, в этом случае проблема, с которой вы столкнулись, можно просто решить, удалив саму функцию из программы.

person Claudio Cortese    schedule 19.01.2016