Предупреждение: неявное объявление функции - почему мой код работает в любом случае?

Я прошел через следующие темы:

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

Основной файл C

#include "node.h"
int main(){
    nd *head=NULL;
    nd *tail=NULL;

    create_node(&head, &tail, 10);
    create_node(&head, &tail, 20);
    create_node(&head, &tail, 15);
    create_node(&head, &tail, 35);
    create_node(&head, &tail, 5);
    create_node(&head, &tail, 25);
    print_list(head, tail);
    create_node(&head, &tail, 55);
    create_node(&head, &tail, 52);
    create_node(&head, &tail, 125);

    printf("%d\n",tail->data);
    printf("%d\n",head->data);
    print_list(head, tail);
    return 0;
}

node.hфайл

#ifndef NODE_H
#define NODE_H

#include<stdio.h>
#include<stdlib.h>

typedef struct node{
    int data;
    struct node *next;
    struct node *prev;
}nd;

void insert_node(nd **head, nd **tail, int data);

void print_list(nd *head, nd *tail);

#endif

node.cфайл

#include "node.h"
void create_node(nd **head, nd **tail, int d){

    nd *temp=(nd *) malloc(sizeof(nd));
    temp->data=d;
    temp->next=NULL;
    temp->prev=NULL;
    /* Start of the Queue.              */
    if(*head==NULL && *tail==NULL){
        *head=temp;
        *tail=temp;
    }
    /* Linking with tail of the Queue.              */
    else if((*tail)->next==NULL){
        (*tail)->next=temp;
        temp->prev=*tail;
        *head=temp;
    }
    /* Adding remaining elements of the Queue.      */
    else{
        (*head)->next=temp;
        temp->prev=*head;
        *head=temp;
    }
}

void print_list(nd *head, nd *tail){
    if(NULL==head){
        printf("Queue is empty\n");
    }
    else{
        printf("Printing the list\n");
        nd *temp;
        for(temp=tail;temp!=NULL;temp=temp->next){
            printf("%d ",temp->data);
        }
        printf("\n");
    }
}

Выход

Printing the list
10 20 15 35 5 25 
10
125
Printing the list
10 20 15 35 5 25 55 52 125 

Имя функции, объявленной в node.h является insert_node тогда как в node.c это create_node, Может кто-нибудь поделиться какой-то информацией о том, почему он работает? Это бросает предупреждение, хотя:

Предупреждение: неявное объявление функции

2 ответа

Решение

Во-первых, вы объявили функцию с именем insert_node, но это не имеет значения. Можно объявлять функции, но не определять их (т.е. не предоставлять их код), если вы не используете функцию. Это часто случается в реальной жизни: заголовки определяют множество функций, а затем во время соединения должны быть предоставлены только те функции, которые фактически используются.

Предупреждение касается create_node, Так как при компиляции основного файла C отсутствует объявление функции, компилятор делает некоторые предположения о типах ее параметров. Он продвигает все аргументы: целочисленные типы меньше, чем int (например char а также short) повышены до int; floats повышены до double; типы указателей не конвертируются. С вашим кодом это работает, потому что

  • вы всегда передаете аргументы правильного типа;
  • ни один из типов аргументов не продвигается.

Если вы изменили тип data параметр для longто компилятор сгенерирует код для вызова функции, предполагая int типа, но функция будет ожидать long аргумент. На платформе, где int а также long имеют разные размеры, вы можете получить мусорные данные, сбой или другое неправильное поведение.

Если вы изменили тип data параметр для charто компилятор сгенерирует код для вызова функции, предполагая int типа, но функция будет ожидать char аргумент. Опять же, вы можете обнаружить, что код использует неверные данные, сбои и т. Д.

C обычно дает вам достаточно веревки, чтобы повеситься. Если вы порежете кусок веревки неправильно, это может сработать. Или это не так.

В вашем примере у вас есть неявное объявление create_node и объявить невыполненную функцию insert_node,

Звонки в create_node работать по причинам, которые будут рассмотрены в предыдущих постах, на которые вы ссылаетесь.

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

Я уверен, что вы это знаете, но правильный подход заключается в стандартизации на одном из create_node или же insert_node и используйте это всюду по своей программе.

Другие вопросы по тегам