2013-10-28 42 views
1

我无法编译我的tldlist.c文件。C编译器错误:冲突类型,指针转换不兼容整数

我如何解决这些问题:

  • 隐式声明
  • 冲突的类型
  • 不相容的整数指针转换
  • 静态声明如下非静态声明

请忽略未使用的变量/参数警告。我仍然没有实现一些方法。

注意:tldlist.h不能以任何方式修改。

编译器错误:

bash-3.2$ gcc -c -W -Wall tldlist.c 
tldlist.c:86:21: warning: implicit declaration of function 'tldnode_create' is invalid in C99 [-Wimplicit-function-declaration] 
    TLDNode *node = tldnode_create(tld_name); 
        ^
tldlist.c:86:14: warning: incompatible integer to pointer conversion initializing 'TLDNode *' (aka 'struct tldnode *') with an expression of 
     type 'int' [-Wint-conversion] 
    TLDNode *node = tldnode_create(tld_name); 
      ^ ~~~~~~~~~~~~~~~~~~~~~~~~ 
tldlist.c:92:10: warning: implicit declaration of function 'tldlist_add_node' is invalid in C99 [-Wimplicit-function-declaration] 
    if (!tldlist_add_node(tld, tld_name, tld->root)) 
     ^
tldlist.c:71:7: warning: unused variable 'comparison' [-Wunused-variable] 
    int comparison; 
    ^
tldlist.c:110:12: error: static declaration of 'tldlist_add_node' follows non-static declaration 
static int tldlist_add_node(TLDList *tld, char *tld_name, TLDNode *node) { 
     ^
tldlist.c:92:10: note: previous implicit declaration is here 
    if (!tldlist_add_node(tld, tld_name, tld->root)) 
     ^
tldlist.c:121:14: warning: incompatible integer to pointer conversion initializing 'TLDNode *' (aka 'struct tldnode *') with an expression of 
     type 'int' [-Wint-conversion] 
    TLDNode *new = tldnode_create(tld_name); 
      ^ ~~~~~~~~~~~~~~~~~~~~~~~~ 
tldlist.c:128:14: warning: incompatible integer to pointer conversion initializing 'TLDNode *' (aka 'struct tldnode *') with an expression of 
     type 'int' [-Wint-conversion] 
    TLDNode *new = tldnode_create(tld_name); 
      ^ ~~~~~~~~~~~~~~~~~~~~~~~~ 
tldlist.c:151:43: warning: unused parameter 'tld' [-Wunused-parameter] 
TLDIterator *tldlist_iter_create(TLDList *tld) { 
             ^
tldlist.c:159:41: warning: unused parameter 'iter' [-Wunused-parameter] 
TLDNode *tldlist_iter_next(TLDIterator *iter) { 
             ^
tldlist.c:174:10: error: conflicting types for 'tldnode_create' 
TLDNode *tldnode_create(char *element) { 
     ^
tldlist.c:86:21: note: previous implicit declaration is here 
    TLDNode *node = tldnode_create(tld_name); 
        ^
8 warnings and 2 errors generated. 

tldlist.c:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include "date.h" 
#include "tldlist.h" 

struct tldlist { 
    struct tldnode *root; 
    long count; 
    long size; 
    Date *begin; 
    Date *end; 
}; 

/* 
* TODO: check the definition of element. 
*/ 
struct tldnode { 
    struct tldnode *parent; 
    struct tldnode *left; 
    struct tldnode *right; 
    char *element; 
    long count; 
}; 

/* 
* TODO: look at lecture slides 
*/ 
struct tlditerator { 
    struct tldlist *tld; 
}; 

/* 
* tldlist_create generates a list structure for storing counts against 
* top level domains (TLDs) 
* 
* creates a TLDList that is constrained to the `begin' and `end' Date's 
* returns a pointer to the list if successful, NULL if not 
*/ 
TLDList *tldlist_create(Date *begin, Date *end) { 
    TLDList *tldl = (TLDList *)malloc(sizeof(TLDList)); 

    if (tldl != NULL) { 
    tldl->root = NULL; 
    tldl->count = 0; 
    tldl->begin = date_duplicate(begin); 
    tldl->end = date_duplicate(end); 
    } 
    return tldl; 
}; 

/* 
* tldlist_destroy destroys the list structure in `tld' 
* 
* all heap allocated storage associated with the list is returned to the heap 
*/ 
void tldlist_destroy(TLDList *tld) { 
    if (tld != NULL) 
    free(tld); 
}; 

/* 
* tldlist_add adds the TLD contained in `hostname' to the tldlist if 
* `d' falls in the begin and end dates associated with the list; 
* returns 1 if the entry was counted, 0 if not 
*/ 
int tldlist_add(TLDList *tld, char *hostname, Date *d) { 
    char *tld_capture; 
    char *tld_name; 
    int tld_length; 
    int comparison; 

    // check if 'd' in the date range 
    if (date_compare(tld->begin, d) > 0 || date_compare(tld->end, d) < 0) 
    return 0; 

    // get TLD from hostname 
    tld_capture = strrchr(hostname, '.') + 1; 
    tld_length = strlen(tld_capture); 
    tld_name = (char *)malloc(sizeof(char)*(tld_length+1)); 
    tld_name[tld_length] = '\0'; 
    strcpy(tld_name, tld_capture); 

    if (tld->root == NULL) { 
    /* insert at root */ 
    TLDNode *node = tldnode_create(tld_name); 
    node->count++; 
    tld->root = node; 
    tld->size++; 
    } else { 
    /* add elsewhere */ 
    if (!tldlist_add_node(tld, tld_name, tld->root)) 
     free(tld_name); 
    else 
     tld->size++; 
    } 

    return 0; 
}; 

/* 
* insert the TLD to the tree 
* consider 5 different cases: 
* (1) TLD name < current and there is a left node 
* (2) TLD name > current and there is a right node 
* (3) TLD name < current and there is no left node 
* (4) TLD name > current and there is no right node 
* (5) TLD name is equal to current 
*/ 
static int tldlist_add_node(TLDList *tld, char *tld_name, TLDNode *node) { 
    int comparison = strcmp(tld_name, node->element); 

    if ((comparison < 0) && (node->left != NULL)) 
    /* case 1 */ 
    return tldlist_add_node(tld, tld_name, node->left); 
    else if ((comparison > 0) && (node->right != NULL)) 
    /* case 2 */ 
    return tldlist_add_node(tld, tld_name, node->right); 
    else if ((comparison < 0) && (node->left == NULL)) { 
    /* case 3 */ 
    TLDNode *new = tldnode_create(tld_name); 
    new->parent = node; 
    new->count++; 
    node->left = new; 
    return 1; 
    } else if ((comparison > 0) && (node->right == NULL)) { 
    /* case 4 */ 
    TLDNode *new = tldnode_create(tld_name); 
    new->parent = node; 
    new->count++; 
    node->right = new; 
    return 1; 
    } else { 
    /* case 5 */ 
    node->count++; 
    return 0; 
    } 
} 
/* 
* tldlist_count returns the number of successful tldlist_add() calls since 
* the creation of the TLDList 
*/ 
long tldlist_count(TLDList *tld) { 
    return tld->count; 
}; 

/* 
* tldlist_iter_create creates an iterator over the TLDList; returns a pointer 
* to the iterator if successful, NULL if not 
*/ 
TLDIterator *tldlist_iter_create(TLDList *tld) { 
    return NULL; 
}; 

/* 
* tldlist_iter_next returns the next element in the list; returns a pointer 
* to the TLDNode if successful, NULL if no more elements to return 
*/ 
TLDNode *tldlist_iter_next(TLDIterator *iter) { 
    return NULL; 
}; 

/* 
* tldlist_iter_destroy destroys the iterator specified by `iter' 
*/ 
void tldlist_iter_destroy(TLDIterator *iter) { 
    free(iter); 
}; 

/* 
* tldnode_create() creates a new node that contains a TLD name 
* returns a pointer to the node if successful, NULL if not 
*/ 
TLDNode *tldnode_create(char *element) { 
    TLDNode *node = (TLDNode *)malloc(sizeof(TLDNode)); 

    if (node != NULL) { 
    node->parent = NULL; 
    node->left = NULL; 
    node->right = NULL; 
    node->count = 0; 
    } 
    return node; 
} 

/* 
* tldnode_tldname returns the tld associated with the TLDNode 
*/ 
char *tldnode_tldname(TLDNode *node) { 
    return node->element; 
}; 

/* 
* tldnode_count returns the number of times that a log entry for the 
* corresponding tld was added to the list 
*/ 
long tldnode_count(TLDNode *node) { 
    return node->count; 
}; 

tldlist.h:

#ifndef _TLDLIST_H_INCLUDED_ 
#define _TLDLIST_H_INCLUDED_ 

#include "date.h" 

typedef struct tldlist TLDList; 
typedef struct tldnode TLDNode; 
typedef struct tlditerator TLDIterator; 

/* 
* tldlist_create generates a list structure for storing counts against 
* top level domains (TLDs) 
* 
* creates a TLDList that is constrained to the `begin' and `end' Date's 
* returns a pointer to the list if successful, NULL if not 
*/ 
TLDList *tldlist_create(Date *begin, Date *end); 

/* 
* tldlist_destroy destroys the list structure in `tld' 
* 
* all heap allocated storage associated with the list is returned to the heap 
*/ 
void tldlist_destroy(TLDList *tld); 

/* 
* tldlist_add adds the TLD contained in `hostname' to the tldlist if 
* `d' falls in the begin and end dates associated with the list; 
* returns 1 if the entry was counted, 0 if not 
*/ 
int tldlist_add(TLDList *tld, char *hostname, Date *d); 

/* 
* tldlist_count returns the number of successful tldlist_add() calls since 
* the creation of the TLDList 
*/ 
long tldlist_count(TLDList *tld); 

/* 
* tldlist_iter_create creates an iterator over the TLDList; returns a pointer 
* to the iterator if successful, NULL if not 
*/ 
TLDIterator *tldlist_iter_create(TLDList *tld); 

/* 
* tldlist_iter_next returns the next element in the list; returns a pointer 
* to the TLDNode if successful, NULL if no more elements to return 
*/ 
TLDNode *tldlist_iter_next(TLDIterator *iter); 

/* 
* tldlist_iter_destroy destroys the iterator specified by `iter' 
*/ 
void tldlist_iter_destroy(TLDIterator *iter); 

/* 
* tldnode_tldname returns the tld associated with the TLDNode 
*/ 
char *tldnode_tldname(TLDNode *node); 

/* 
* tldnode_count returns the number of times that a log entry for the 
* corresponding tld was added to the list 
*/ 
long tldnode_count(TLDNode *node); 

#endif /* _TLDLIST_H_INCLUDED_ */ 
+0

如果你的代码贴其次这将是更容易帮助你[SSCCE(http://sscce.org/) – crashmstr

+0

隐含的声明 - 只是声明它... –

+0

@kfsone一切都很好用date.h. – chuckfinley

回答

4

这些错误是由于缺少原型 - 你在tldlist.c中调用的函数,而编译器还没有看到它的定义。

默认情况下,编译器会假设任何未知函数返回int(传统返回到非常早的C,如果返回类型为int,则可以将返回类型除外)。这就是为什么你得到不兼容类型的消息:)

你需要为编译器提供函数的声明。你可以通过在tldlist.c的顶部添加原型存根或者通过创建一个定义它们的tldnode.h来完成这项工作(因为它似乎主要是缺少与节点相关的功能)。

为tldnode_create的实现是

TLDNode *tldnode_create(char *element) { 

所以你需要声明

TLDNode *tldnode_create(char *element); 

您尝试使用它之前:要么在tldlist.c顶部tldnode.h或其他地方,例如在tldnode结构的解除之后。

/* 
* TODO: check the definition of element. 
*/ 
struct tldnode { 
    struct tldnode *parent; 
    struct tldnode *left; 
    struct tldnode *right; 
    char *element; 
    long count; 
}; 

TLDNode *tldnode_create(char *element); 
+0

辉煌的答案。解决了所有问题。 – chuckfinley

+0

不兼容的类型警告是未知函数的默认返回类型为“int”的结果 - 这是对C初期的返回,当您只需指定返回类型(如果它不是int)时就返回。这是写有效的:puts(char *); main(){puts(“Hello world!”);作为一个完整的程序。 – kfsone

1

始于顶部: 你的第一个警告的功能隐式声明'tldnode_create'。 您应该在.h文件中定义这个函数原型。 考虑到你无法修改它,你应该在你的.c文件的顶部放置一个原型

这会产生级联错误,因为编译器试图通过定义一个返回一个整数的默认原型因此你的下一个警告)关于不兼容的整数指针转换。

此外,为什么声明函数是静态的?

+0

请阅读问题描述。 .h文件不能以任何方式改变。有什么可以解决这个问题?附:我声明函数是静态的,因为它是二叉搜索树插入算法的一部分。看看代码。 – chuckfinley

+0

@Foon为什么不是静态的?如果它不在此C文件外部使用,则最好是声明为静态。国际海事组织,它应该是第一个默认的。 – glglgl

1

您正在调用未在头文件或c文件中定义的函数(在调用之前)。 tldnode_create没有在任何地方声明。增加功能也不是。

从我所能看到的所有错误中,同样是这个问题。

在使用它们之前声明函数。

相关问题