警告:隐式声明函数 - 为什么我的代码仍然有效?

时间:2014-01-16 18:07:56

标签: c function warnings implicit-declaration

我已经完成了以下主题:

可能我的问题是有联系的。但是虽然它们提供了在使用函数之前声明函数原型的解决方案,但我想探索函数名称不匹配时会发生什么。在我的测试中,它仍然可以正常工作。

主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 个答案:

答案 0 :(得分:4)

在您的示例中,您有一个隐式声明create_node并声明一个未实现的函数insert_node

致电create_node工作的原因将在您之前链接的帖子中涵盖。

insert_node未实现的事实对您的程序无关紧要,因为没有人试图调用它。如果您更改了一行以调用insert_node,则会在没有警告的情况下进行编译,但无法与insert_node的未解决的符号错误相关联。

我相信你知道这一点,但这里的正确方法是在create_nodeinsert_node之一进行标准化并在整个程序中使用它。

答案 1 :(得分:4)

首先,您已经声明了一个名为insert_node的函数,但这并不重要。只要不使用该函数,就可以声明函数,但不能定义它们(即不提供它们的代码)。这通常发生在现实生活中:标题定义了很多函数,然后在链接时只需要提供实际使用的函数。

警告涉及create_node。由于在编译主C文件时没有声明该函数,因此编译器会对其参数类型进行一些假设。它提升所有参数:小于int的整数类型(例如charshort)被提升为int; float被提升为double;指针类型未转换。使用您的代码,这可能会起作用,因为

  • 你总是传递正确类型的参数;
  • 没有任何参数类型被提升。

如果您将data参数的类型更改为long,那么编译器将生成代码以调用函数,假设int类型,但该函数将期望{{1参数。在longint具有不同大小的平台上,您可能会收到垃圾数据,崩溃或其他不当行为。

如果您将long参数的类型更改为data,那么编译器将生成代码以调用函数,假设char类型,但该函数将期望{{1参数。同样,您可能会发现代码使用了错误的数据,崩溃等等。

C通常会给你足够的绳索来吊死自己。如果你以错误的方式切断一根绳子,它可能恰好工作。或者它可能不会。