如果extern关键字既不是,也不是 初始化值存在, 声明可以是声明 或定义。这取决于 编译器来分析模块 计划和决定。
关于C,我无法完全理解这句话的含义。例如,它是否意味着:
int i;
不一定是声明(正如我原先假设的那样),但也可以是一个定义(根据同一网页上的定义和声明的定义,没有双关语)?
简而言之,就是上述声明: 一个。只是一个声明,或 湾声明+定义?
参考:Variable declaration and definition
收到的答案摘要:
Declaration Definition Tentative Definition Initialized int i; (inside a block) Yes Yes No No int i=5; (inside a block) Yes Yes No Yes(to 5) int i; (otherwise) Yes No Yes Yes(to 0) extern int i; Yes No No No All definitions are declarations but not vice-versa.
答案 0 :(得分:15)
假设它在文件范围内,它是一个'暂定的'。从6.9.2 / 2“外部对象定义”:
具有没有初始化程序的文件范围的对象的标识符声明,以及 没有存储类说明符或存储类说明符静态,构成一个 暂定的定义。如果翻译单元包含一个或多个临时定义 然后,标识符和转换单元不包含该标识符的外部定义 行为就像翻译单元包含该文件范围声明一样 标识符,具有复制类型,如翻译单元的末尾,带有初始化程序 等于0。
这意味着在翻译单元中也有以下内容:
int i = 42;
因为该声明具有显式初始化器,所以它是变量i
的定义。
如果声明属于块范围,则标准说明如下(6.2.2 / 2“标识符链接”):
标识符的每个声明 没有联系表示一个独特的实体。
...
(第6段)以下内容 标识符没有链接:... a 阻止对象的范围标识符 声明没有存储类 说明者extern。
因此在块范围内,声明也是一个定义。
答案 1 :(得分:14)
C标准说
标识符的定义是该标识符的声明:对于对象,导致为该对象保留存储空间(...)
定义包含声明,即每个定义都必须是声明,所以说
是没有意义的。int i;
不是声明。 是一个也恰好是定义的声明。或者,它是一个定义,因此是一个声明。
答案 2 :(得分:4)
在变量的上下文中:
变量声明是一个描述此变量外观的语句。所以:
extern int x;
全局范围内的转换为:“代码中的某处,有一个名为x
的变量,其类型为int
和外部链接。在您引用x
之前,必须声明(同样适用于函数声明。)
定义是一个创建此变量实例的语句。所以:
int x;
全局范围内的创建一个具有extern链接的int
类型的单个变量。因此,如果您将该行放在标题中,则包含该标题的每个翻译单元都会尝试创建自己的x
副本,这是不可取的 - 这就是我们只在头文件中声明的原因。功能也是如此:如果你提供功能体,那就是一个定义。
另外,正式地说,每个定义都是一种声明,因为它还必须指定此变量/函数的外观 - 所以如果给定范围中已存在定义,则不需要使用任何其他声明它
答案 3 :(得分:1)
来自C99规范:
具有没有初始化程序的文件范围的对象的标识符声明,以及 没有存储类说明符或存储类说明符静态,构成一个 暂定的定义。如果翻译单元包含一个或多个临时定义 然后,标识符和转换单元不包含该标识符的外部定义 行为就像翻译单元包含该文件范围声明一样 标识符,具有复制类型,如翻译单元的末尾,带有初始化程序 等于0。
因此,这是一个没有初始化程序的简单声明可以作为声明的情况。
答案 4 :(得分:1)
由于C使用以下术语:
“定义”会产生某种东西(占据某种记忆)。它还描述了一些东西。这意味着“定义”也是“声明”。
“声明”只描述了一些内容。这个想法是编译器需要知道如何构建使用其他地方定义的东西的代码。之后,链接器会将使用链接到某个东西。
声明允许您编译代码并将其链接(稍后)作为单独的步骤。