Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么c++;编译程序?静态int x=x;_C++_Static_Initialization - Fatal编程技术网

C++ 为什么c++;编译程序?静态int x=x;

C++ 为什么c++;编译程序?静态int x=x;,c++,static,initialization,C++,Static,Initialization,我刚刚发现: static int x = x; 为什么这个初始化被C++编译器接受? 我会称之为编译器异常,但可能有人会对此给出很好的解释 因此,对于静态存储的数据,可以使用自身初始化变量。。。我尝试过使用VS2015和VS2017编译器以及一些其他的在线C++编译器。 < p>实际上对于静态< /COD>和非->代码> static < /COD>变量。 名称在声明符之后和初始化之前(如果有)立即可见。因此 static int x = x; 名称x在第一次出现后立即可见,可以在初始值设

我刚刚发现:

static int x = x;
为什么这个初始化被C++编译器接受?

我会称之为编译器异常,但可能有人会对此给出很好的解释


因此,对于静态存储的数据,可以使用自身初始化变量。。。我尝试过使用VS2015和VS2017编译器以及一些其他的在线C++编译器。

< p>实际上对于<代码>静态< /COD>和非->代码> static < /COD>变量。 名称在声明符之后和初始化之前(如果有)立即可见。因此

static int x = x;
名称
x
在第一次出现后立即可见,可以在初始值设定项中引用。因为它是静态的,所以它的初始值定义得很好(它是
0

即使在区块范围内,这也是合法的:

int x = x;
尽管在这里您可能会收到警告,因为
x
正在使用其自身的不确定值进行初始化(在大多数情况下,行为是未定义的)

这是一件愚蠢的事情,但是C++并不是为了阻止你做傻事。例如,您可能希望声明一个指向自身的指针:

void *p = (void*)&p;

在这里,初始值设定项指的是
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 x=(scanf(“%d”,&x),x)
intx=xat块是UB:不确定值(无符号字符类型除外)的计算是立即UB,不确定值不会像C11中那样部分传播+DR451@M.M那么,
无符号字符x=x
do,如果它不是未定义的?@DanielH与
unsigned char x相同。参见[basic.scope.pdecl],确实存在一些很酷的用例;也就是说,它的效用甚至超过了给出的小例子。回答得好!无需强制转换到
void*
,只需分配即可。