十字架初始化有什么迹象?

Jic*_*hao 81 c++ initialization

考虑以下代码:

#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;
    };
}
Run Code Online (Sandbox Code Playgroud)

G ++抱怨.crosses initialization of 'int r'我的问题是:

  1. 什么是crosses initialization
  2. 为什么第一个初始化程序x + y通过编译,但后来失败了?
  3. 所谓的问题是什么crosses initialization

编辑:
我知道我应该使用括号来指定范围,r但我想知道为什么,例如为什么在多案例switch语句中无法定义非POD.

谢谢.

ava*_*kar 94

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

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

您可以做的最好的事情是限制变量的范围.这样你就可以满足编译器和阅读器的需要.

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

标准说(6.7/3):

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

  • 好吧,我的g ++没有.再次检查或升级编译器. (10认同)

Pét*_*rök 35

你应该把case括号中的内容放到它的范围内,这样你就可以在其中声明局部变量:

switch(i) {
    case 1:
        {
            // int r = x + y; -- OK
            int r = 1; // Failed to Compile
            cout << r;
        }
        break;
    case 2:
        ...
        break;
};
Run Code Online (Sandbox Code Playgroud)