【问题标题】:Declaration vs definition in CC中的声明与定义
【发布时间】:2015-10-16 05:15:18
【问题描述】:

考虑代码:

int main(void)
{
    int a;
}

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

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

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

...

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

【问题讨论】:

  • 一个定义永远是一个定义,即使没有被使用(即使编译器实际上并没有发出代码或为它保留空间)。
  • @JoachimPileborg 标准有点模棱两可,它肯定说:导致存储被保留...。然后在整个标准中,该术语可以互换使用,例如他们称int* p;声明。整个讨论开始here
  • @RahulTripathi 不,这不是骗子,我想要一个符合标准的答案,这也是语言律师标签的原因。

标签: c language-lawyer


【解决方案1】:

您从 6.7/5 中引用的文本实际上是要以与您所做的相反的方式解释:文本是说定义导致分配存储。

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

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

【讨论】:

  • 令我困惑的是他们指的是例如const int *ptr_to_constant; 作为声明,参见 6.7.6.1/3(我链接的文档的第 130 页)。从技术上讲,它是正确的,因为定义也可以是声明......
  • @vsoftco 所有定义都是声明,因此术语是正确的(尽管可能具有误导性)
  • 是的,可能就是这样。但抽象机器无疑是正确的思考方式。但是int f(); main(){} int f(){return 0;}int f(){return 0;} 不只是一个定义吗?或者你在谈论变量?
  • @vsoftco,不,这也是函数mainf的声明,但是没有“原型”的声明。
【解决方案2】:

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

是的。

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

【讨论】:

    【解决方案3】:
    int a;
    

    这是一个定义 为变量a分配了内存

    extern int a;
    

    这是一个声明。 由于未定义内存,因此未分配内存。

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

    【讨论】:

      【解决方案4】:

      声明引入了一个标识符并描述了它的类型,无论是类型、对象还是函数。声明是编译器需要接受对该标识符的引用。这些是声明:

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

      定义实际上实例化/实现了这个标识符。这是链接器将引用链接到这些实体所需要的。这些是与上述声明相对应的定义:

      int bar;
      int g(int lhs, int rhs) {return lhs*rhs;}
      

      【讨论】:

        猜你喜欢
        • 2015-06-28
        • 1970-01-01
        • 2013-11-15
        • 1970-01-01
        • 2011-06-13
        • 1970-01-01
        • 2015-06-30
        • 1970-01-01
        • 2018-12-22
        相关资源
        最近更新 更多