十字架初始化的迹象是什么?

2022-01-18 00:00:00 initialization c++

考虑以下代码:

#include <iostream>
using namespace std;

int main()
{
    int x, y, i;
    cin >> x >> y >> i;
    switch(i) {
        case 1:
            // int r = x + y; -- OK
            int r = 1; // Failed to Compile
            cout << r;
            break;
        case 2:
            r = x - y;
            cout << r;
            break;
    };
}

G++ 抱怨 跨过 'int r' 的初始化.我的问题是:

G++ complains crosses initialization of 'int r'. My questions are:

  1. 什么是交叉初始化?
  2. 为什么第一个初始化器x + y编译通过,而后者却失败了?
  3. 所谓crosses初始化有哪些问题?
  1. What is crosses initialization?
  2. Why do the first initializer x + y pass the compilation, but the latter failed?
  3. What are the problems of so-called crosses initialization?

我知道我应该用括号来指定r的范围,但是我想知道为什么,例如为什么不能在多案例switch语句中定义非POD.

I know I should use brackets to specify the scope of r, but I want to know why, for example why non-POD could not be defined in a multi-case switch statement.

推荐答案

int r = x + y;的版本也不会编译.

问题是 r 有可能在没有执行初始化程序的情况下进入作用域.如果您完全删除了初始化程序,代码将编译得很好(即该行将读取 int r;).

The problem is that it is possible for r to come to scope without its initializer being executed. The code would compile fine if you removed the initializer completely (i.e. the line would read int r;).

你能做的最好的事情就是限制变量的范围.这样你就可以让编译器和读者都满意了.

The best thing you can do is to limit the scope of the variable. That way you'll satisfy both the compiler and the reader.

switch(i)
{
case 1:
    {
        int r = 1;
        cout << r;
    }
    break;
case 2:
    {
        int r = x - y;
        cout << r;
    }
    break;
};

标准说 (6.7/3):

The Standard says (6.7/3):

可以转移到块中,但不能通过初始化绕过声明.从具有自动存储持续时间的局部变量不在范围内的点跳转到它在范围内的点的程序是格式错误的,除非该变量具有 POD 类型 (3.9) 并且在没有初始化程序 (8.5) 的情况下声明.

It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A program that jumps from a point where a local variable with automatic storage duration is not in scope to a point where it is in scope is ill-formed unless the variable has POD type (3.9) and is declared without an initializer (8.5).

相关文章