Предупреждение: неявное объявление функции - почему мой код работает в любом случае?
Я прошел через следующие темы:
Возможно, моя проблема связана. Но хотя они и предлагают решение о том, что прототип функции должен быть объявлен до ее использования, я хотел изучить, что происходит, когда имя функции не совпадает. В моем тесте все равно работает нормально.
Основной файл 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
; float
s повышены до 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
и используйте это всюду по своей программе.