为什么需要在初始化时指定extern / static变量的类型?

时间:2015-04-17 14:56:45

标签: c++ static extern

我不明白在初始化时需要指定extern / static变量的类型。例如:

struct Test{
 static int i;
};
 Test::i = 2; //error
 int Test::i = 2; //ok

编译器是否知道我的类型为int?它只是编译器的特殊性,或者为什么是类型的规范,int"需要的?

4 个答案:

答案 0 :(得分:3)

  

我不明白在初始化时需要指定extern / static变量的类型。

因为语言设计者选择对变量声明和定义使用相同的语法。该语法包括类型名称。你是对的,在某些情况下,这个类型名称是多余的。但是允许你把它遗漏可能有些令人困惑:它看起来像是一个任务,而不是一个定义。

  

编译器是否知道我的类型为int?

仅在已声明变量的情况下。对于像这样的静态成员,情况必须如此,但不一定是全局变量。您可以在一个源文件中声明它:

extern int i;

并在另一个

中定义它
int i = 42;

没有使声明可用于定义。

答案 1 :(得分:1)

这是基本语法的问题。

C ++文件由一系列声明组成。变量声明的基本语法如下:

  

type identifier initializer opt ;

我遗漏了很多细节,但这是基本的想法:文件范围内的内容必须是声明,变量声明必须以名称开头一种类型。

在开头没有类型名称的情况下,您有一个简单的赋值语句 - 但这些只能在函数内部使用,而不是在文件范围内,因为您已尝试在此处执行此操作。

答案 2 :(得分:1)

这个"限制"可以简化为简单的语法:声明

Test::i = 2; //error

是一个由赋值表达式组成的表达式语句。这实际上从未被解析为声明,无论实体Test::i可能是什么,并且调整语法来覆盖它将是非常复杂的并且没有任何好处。

答案 3 :(得分:1)

这是一个有效的,可运行的代码的例子,如果在整数N::X::i的定义中没有指定类型,它将变得不明确,因为结构可能使用消除歧义struct但是没有任何等同于强制int X::i定义与您提议的语法下的struct不匹配。

#include <iostream>

namespace N
{
  struct X
  {
    static int i;
    struct i { int n_; };
  };
}

int n = 2;

namespace N
{
  int X::i (n);   // take int out and under current C++ rules
                  // it will be equivalent to the next line
                  // (which is equivalent to struct X::i n; btw)
  struct X::i (n); // but under your proposed rules, ambiguous
}

int main()
{
    std::cout << N::n.n_ << ' ' << N::X::i << '\n';
}

这有点令人费解,但最重要的是:没有提到的类型可能会破坏东西。

其他答案基本上等于与其他情况下出现的变量定义的一致性 - 这是可取的,但不是一个合理的技术驱动因素来决定问题中提出的简化。当然,它可能不足以简化,或者可能被视为更多的混淆,防止它被认真考虑用于标准化。