为什么c++编译器接受这种初始化?静态int x=x
Why is this initialization accepted by the c++ compiler? static int x = x;
我刚刚发现了这个:
static int x = x;
为什么C++编译器接受这种初始化?
我会称之为编译器异常,但有人可能会对此做出很好的解释。
因此,对于具有静态存储的数据,可以用自身初始化变量。。。我已经在VS2015和VS2017编译器以及其他一些在线C++编译器中尝试过这一点。
对于static
和非static
变量,它实际上是相同的。
名称在其声明符之后以及初始化之前(如果有的话)立即可见。因此在中
static int x = x;
名称x
在其第一次出现之后立即变得可见并且可以在初始化器中被引用。由于它是静态的,所以它的初始值定义得很好(它是0
)。
即使在区块范围内,这也是合法的:
int x = x;
尽管在这里您可能会收到警告,因为x
正在使用其自己的不确定值进行初始化(在大多数情况下,行为是未定义的)。
这是一件愚蠢的事情,但C++并不是为了阻止你做愚蠢的事情。例如,您可能想要声明一个指向自身的指针:
void *p = (void*)&p;
这里的初始值设定项指的是p
的地址,而不是它的值,但名称p
必须是可见的才能起作用。添加一条特殊情况规则被认为是不值得的。
如果你想禁止C++中所有愚蠢的构造(当然还有C),你会得到一个很长的列表。
与C相比,C++实际上是一种非常不同的语言,但它仍然有其根源。而且,至少在一开始,对与C兼容的关注是非常强烈的。即使在今天,C++标准也包含了用于此目的的C头。
许多奇怪的事情都可以追溯到C语言,而C语言对编译器的要求很低,但对程序员的要求更高。许多构造产生未定义的行为或不确定的值。这主要有两个原因。首先,它使正确编写编译器变得更容易,并且对系统的要求更低。这在C的早期很重要。这种语言出现在1972年,也就是Commodore发布具有4kB内存的家用电脑VIC-20的8年前。其次,它允许编译器以更少的内存使用率生成更快的代码,正如刚才提到的,这在过去非常重要。
因此,即使根本没有任何有效的用例(即使我看不到它,我也不排除它可能存在的可能性),也没有足够的理由对此采取行动
正如Keith在回答中提到的,如果变量是静态的,那么它的值将为0,这意味着该值不是不确定的。static int x = x;
的结果是完全清楚的,为什么禁止它呢?你会让C++规范变得更大、更难维护,并可能破坏一些旧代码,只是为了解决一些不成问题的问题。
当涉及到非静态变量时,这是另一回事,因为值是不确定的。这里有一个更好的理由来禁止这个构造,但另一方面,你已经收到了警告。至少如果你正在使用-Wall
,你应该这样做。我还可以补充一点,许多警告都是警告,而不是错误,只是为了不破坏旧代码。但是,与其禁止初始化本身,不如完全禁止使用未初始化的变量。
- 枚举成员与静态 int 成员?
- 如何使用静态多态性在 int 和指针类型之间进行转换?
- 将 static_cast<int>(-15) 分配给静态常量字符类型变量
- std::out_of_range 在静态 int 变量上
- 打印一个带有静态 int 的函数,有一个 std::cout 和多个 std::cout 有什么区别?
- 错误:无效使用非静态成员函数"int test::hotplug_callback(libusb_contex
- 覆盖性静态分析说无符号的int是char(C++)
- C 未解决的外部符号(公共静态INT)
- 如何添加到静态 int +1
- 为什么c++编译器接受这种初始化?静态int x=x
- 静态 int 和 int 在 C++ 类中的区别
- 静态 (<int>PASS_OBJECT) 模板化数组在创建所述类型的对象时丢失数据?
- 静态 int 初始化
- 在这种情况下,静态 int 的值会发生变化吗?
- C++ 将静态 int 的值赋值分配给 int
- 具有大的2d数组:静态int与int
- 如何在c++函数中声明和初始化静态int
- 静态int数组中的类问题
- 静态int执行多少次
- c++ 使用 CLI 数组初始化值静态 int