外部声明中的警告

时间:2010-11-24 15:42:17

标签: c

#include<stdio.h>
#include<stdlib.h>
#define GREY 1
#define BLACK 0
#define WHITE 2
typedef struct node * graph;
typedef struct stack * snode;

graph cnode(int data);          //cnode is to create a node for graph
void cgraph(void);
struct node {
        int data, color;
        struct node *LEFT, *RIGHT, *TOP, *DOWN;
};//this structure defines a node of the graph

struct stack {
struct stack *priv;
struct cgraph *graph_node;
};// this is to define a structure which should hold node of a structure

    extern snode sroot;

我定义了一个头文件(declaration.h),如下所示,以下是一个c程序(stack.c) 我正在制作哪些将在我正在开发的图书馆中使用

#include<declarations.h>
void cstack (graph temp);
void stackpush(snode stemp);
extern int stack_counter = 0;

sroot=NULL;
void cstack (graph gtemp) //cstack is to create stack
{
   snode spriv,some;
  if (stack_counter==0)
  {
   sroot=stackpush(gtemp);
    spriv=sroot;
   stack_counter++;
   }
   else{
   some=cstacknode(gtemp);
    some->priv=spriv;
    spriv=some;
  }

}

//struct stack is representing a stack
//struct node is representing a node in graph

snode  cstacknode (graph gtemp)
//this function should create a node of the stack which should be storing the graph node as a pointer
{
 snode an;
 an=(snode)malloc(sizeof(snode));
 an->graph_node=gtemp;
 an->priv=NULL;
 return an;
}

void stackpush(snode stemp)
{

}

以上两个文件都在同一目录中。 我编译了上面的文件stack.c cc -I ./ stack.c我发出警告

stack.c:4: warning: ‘stack_counter’ initialized and declared ‘extern’
stack.c:6: warning: data definition has no type or storage class
stack.c:6: error: conflicting types for ‘sroot’
./declarations.h:21: note: previous declaration of ‘sroot’ was here
stack.c:6: warning: initialization makes integer from pointer without a cast
stack.c: In function ‘cstack’:
stack.c:12: warning: passing argument 1 of ‘stackpush’ from incompatible pointer type
stack.c:3: note: expected ‘snode’ but argument is of type ‘graph’
stack.c:12: error: void value not ignored as it ought to be
stack.c:13: warning: assignment makes pointer from integer without a cast
stack.c:17: warning: assignment makes pointer from integer without a cast
stack.c: At top level:
stack.c:27: error: conflicting types for ‘cstacknode’
stack.c:17: note: previous implicit declaration of ‘cstacknode’ was here
stack.c: In function ‘cstacknode’:
stack.c:32: warning: assignment from incompatible pointer type

我想知道当我将变量声明为extern并且我已经标记为粗体时,为什么我会将此作为警告对此有任何想法,如果有人想要在剩余错误上分享任何其他事情,请告诉我。 / p>

4 个答案:

答案 0 :(得分:32)

虽然您的代码包含许多相当严重且明显的错误(已在其他答案中介绍过),但您在问题标题中添加的警告是完全无意义的无意义警告。 GCC编译器因发布无用警告而臭名昭着。许多这些警告似乎来自于某人的无能和完全没有事实根据的信念,即做某事在某种程度上是“错误的”,而实际上它没有任何问题。

在您的情况下,警告由

触发
extern int stack_counter = 0;

声明。显然,警告的“作者”认为extern说明符应该保留用于非定义声明。在这种情况下,初始化程序= 0的存在将声明转换为定义(因此正式使extern可选)。尽管如此,它并没有错误,事实上,extern可能非常受欢迎,以强调stack_counter旨在成为全局变量的事实。

同样,您是否需要全局变量是一个不同的问题,同样,您的代码包含大量其他错误。但是你似乎关注的警告并不值得。只需在编译器设置中禁用此警告(并且,请向GCC团队写一封粗略的信件)。

答案 1 :(得分:5)

头文件中的extern声明允许除定义变量之外的模块使用它。如果它应该被定义为int stack_counter = 0并且存在于stack.c中,那就像这样定义并在标题中放置一个extern stack_counter

在stack.c的第6行,您没有为sroot定义存储类。由于它在标题中被删除,我假设您打算键入snode sroot=NULL

修复那些,然后实现stackpush(确保它不返回void)并按顺序处理其余的警告。请注意,在C中,您必须使用函数的前向声明(使用原型)或在使用之前定义函数。 cstack函数可能应该是文件中的最后一个函数。

答案 2 :(得分:0)

Clang仍对此发出警告。线

extern int counter = 0;

将触发警告:

警告:“ extern”变量具有初始化程序[-Wextern-initializer]

此警告并不重要,因为使用

定义变量
int counter = 0;

在默认情况下仍会产生静态持续时间和外部链接。实际上,如果未提供存储类说明符,则默认值为:

  • extern用于所有功能
  • extern用于文件范围内的对象
  • auto用于块范围内的对象

还有一个称为临时定义的东西,它是一个没有初始化程序,没有存储类说明符或带有说明符static的外部声明。

临时定义是可以或可以不用作定义的声明。如果在同一个翻译单元中早晚发现了实际的外部定义,则暂定定义仅充当声明。

所以下面一行

int counter;

临时定义,它使用隐式初始化程序counter声明和定义= 0(对于数组,结构和联合类型,则= {0}

答案 3 :(得分:0)

我刚刚在gcc收到了这个警告,这很简单。 stack_counter不应在标头中初始化,而应在包含它的源文件中初始化。所以标题应该只使用:

extern int stack_counter;

然后在仅包含该标头的一个源文件的全局范围内声明并初始化stack_counter:

int stack_counter = 0;