2015-10-16 70 views
2

定义考虑代码:宣言VS用C

int main(void) 
{ 
    int a; 
} 

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

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

- 为一个对象,使存储到该对象保留;

...

问题来了:编译器可以优化掉的存储,因为我们没有使用变量。然后int a;一个声明呢?而如果我们在一个main(void)printf("%p", &a)做 - 当然现在的编译器分配存储空间,所以是声明/定义的概念依赖于你是否以后使用标识符或没有?

+0

的定义是总的定义,即使不使用(并且甚至当编译器实际上不发射码或保留空间为它)。 –

+0

@JoachimPileborg这个标准有点含糊不清,它肯定地说:*导致存储保留... *。然后贯穿整个标准,该术语可互换使用,例如,他们调用'int * p;'a *声明*。整个讨论开始[here](http://stackoverflow.com/a/33159989/3093378) – vsoftco

+0

[定义和声明之间有什么区别?](http://stackoverflow.com/questions/ 1410563 /定义和声明之间的区别是什么) –

回答

5

从6.7/5引用的文本实际上是为了解释周围比你做了什么其他的方式:文字是说,定义导致存储进行分配。

指定int a;是定义的文本在别处。

C是根据抽象机器来定义的。抽象机器中分配了存储空间。是否在您的PC上分配任何内存是不相关的。

+0

让我感到困惑的是他们指的是'const int * ptr_to_constant;'作为*声明*,见6.7.6.1/3(链接文档的第130页)。从技术上讲,这是正确的,因为一个定义也可以是一个声明... – vsoftco

+0

@vsoftco所有的定义都是声明,所以术语是正确的(尽管也许是误导) –

+0

是的,这可能是怎么回事。但抽象机器当然是正确的思考方式。但是'int f(); main(){} int f(){return 0;}不是'int f(){return 0;}'只有一个定义吗?或者你在谈论变量? – vsoftco

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;}