【问题标题】:Strange GCC warning on storage class and type关于存储类和类型的奇怪 GCC 警告
【发布时间】:2011-10-09 11:47:40
【问题描述】:

我有一个看起来像这样的头文件

header.h

int TOS;

这个文件只包含在一个代码文件中

code.c

#include "header.h"
TOS=0;

编译 code.c 时 GCC 发出警告

code.c:3:1: 警告:数据定义没有类型或存储类[默认启用] code.c:3:1:警告:在“TOS”声明中类型默认为“int”[默认启用]

我无法理解此警告的原因。不就相当于在code.c中声明和定义TOS吗?即

code.c

int TOS;
TOS=0;

【问题讨论】:

  • 你有main() 对吗?
  • 是的 main() 在那里。为简洁起见省略了它。
  • TOS=0;inside main()?

标签: c gcc gcc-warning


【解决方案1】:

因为你在全局范围内定义了TOS,所以需要你定义TOS的类型(它是一个声明),如果没有给出类型,默认是int

这将导致conflicting type error

char x;
x = 0;

【讨论】:

  • 但是为什么不能声明一个全局并在以后定义它呢??
  • @我想是因为编译器只允许在全局范围内声明和初始化变量,不允许赋值。
【解决方案2】:

在头文件中转发变量的正确方法是

extern int TOS;

如果没有extern,这可能会导致TOS 被分配到多个编译单元(.o 文件)中。

然后你会在一个 .c 文件中给出一个定义

int TOS;

这将为它保留空间,并且由于它是全局范围内的变量,因此它还将将其初始化为0。如果你想显式地初始化这个初始化,或者如果你想让它成为除0之外的另一个值,那么初始化的正确语法(而不是赋值)是

int TOS = 54;

现代 C 不允许您似乎从某处继承的语法,即定义具有隐式类型 int 的全局变量。

【讨论】:

  • 虽然TOS 会在多个翻译单元中分配,但在 C 中(但不是在 C++ 中),链接器应该将它们合并为一个。
  • @ninjalj,不,我不这么认为。我认为只有在没有初始化的情况下才会出现这种情况。 如果用外部链接声明的标识符在表达式中使用.. 在整个程序的某个地方,该标识符应该有一个外部定义;否则,不得超过一个。
  • int TOS; from header.h 是一个带有外部链接的暂定定义。您可以包含来自多个翻译单元的header.h,链接器会将它们合并为一个。
【解决方案3】:

TOS=0 不是赋值,它是带有初始化器的声明(即:定义)。 int TOS; 是一个带有外部链接的暂定定义。当链接器将几个翻译单元链接在一起时,它会折叠相应的对象(=变量的内存)。正如在其他地方所说,int 的默认类型是标准的后续版本中缺少的 C89 功能。

【讨论】:

  • 不。首先,C 标准中没有临时声明之类的东西,只有 临时定义。然后暂定定义要求没有初始化器:一个对象的标识符声明,该对象具有文件范围而没有初始化器,并且没有存储类说明符或具有存储类说明符静态,构成暂定定义.
猜你喜欢
  • 2012-03-04
  • 1970-01-01
  • 2010-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多