C语言中的声明和定义有什么区别?

3

请考虑下面的代码:

int main(void)
{
    int a;
}

据我所知,int a;是一个定义,因为它会导致存储被保留。引用C标准(N1570委员会草案-2011年4月12日):

6.7/5 语义 声明指定一组标识符的解释和属性。标识符的定义是对该标识符的声明,它:

— 对于对象,导致为该对象保留存储空间;

...

现在问题来了:编译器可能会优化掉存储,因为我们没有使用变量。那么int a;是一个声明吗?如果我们在main(void)中执行printf("%p", &a),编译器肯定要分配存储空间,那么声明/定义的概念是否取决于您稍后是否使用标识符呢?

定义始终是定义,即使未被使用(甚至编译器实际上不会生成代码或为其保留空间)。 - Some programmer dude
@JoachimPileborg 嗯,标准有点模糊,它确实说:*导致存储被保留...*。然后在整个标准中,该术语被交替使用,例如,他们称 int* p;声明。整个讨论始于这里 - vsoftco
可能是什么是定义和声明的区别?的重复问题。 - Rahul Tripathi
@RahulTripathi 不,这不是重复的问题,我想要一个符合标准的答案,这也是为什么使用了“语言律师”标签。 - vsoftco
4个回答

5

你引用的6.7/5中的文本实际上应该被解释为与你所做的相反:这个文本是在说定义会导致存储分配。

指定int a;是定义的文本在其他地方。

C语言是根据抽象机器定义的。在抽象机器中分配了存储空间。你的PC是否分配任何内存是无关的。


让我困惑的是,他们将例如 const int *ptr_to_constant; 称为声明,参见6.7.6.1/3(我链接的文档第130页)。从技术上讲,这是正确的,因为定义也可以是声明... - vsoftco
@vsoftco 所有的定义都是声明,因此术语是正确的(尽管可能会误导)。 - M.M
是的,这可能就是发生的事情。但抽象机器肯定是正确的思考方式。但是int f(); main(){} int f(){return 0;}怎么办?int f(){return 0;}不仅仅是定义吗?或者你在谈论变量? - vsoftco
@vsoftco,这不仅是函数mainf的声明,而且是没有“原型”的声明。 - Jens Gustedt

2

那么int a;是一个声明吗?

是的。

实际上,每个定义也都是一个声明。一个变量只能有一个定义,但可以有多个声明。


2
int a;

这是一个定义。

变量 a 有一块内存被分配。

extern int a;

这是一个声明。

由于未定义,因此不分配内存。

一旦变量被定义,您可以使用其地址,这是完全合法的。


0

声明引入标识符并描述其类型,无论是类型、对象还是函数。声明是编译器需要接受对该标识符的引用所需的内容。以下是声明:

extern int bar;
extern int g(int, int);

一个定义实际上实例化/实现了这个标识符。这是链接器需要的,以便将对这些实体的引用链接起来。这些是对上述声明相应的定义:
int bar;
int g(int lhs, int rhs) {return lhs*rhs;}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接