Каковы знаки перекрестной инициализации?

Рассмотрите следующий код:

#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 ++ жалуется crosses initialization of 'int r'Вопросы о.My:

  1. Что crosses initialization?
  2. Почему делают первый инициализатор x + y передать компиляцию, но позже неудавшийся?
  3. Каковы проблемы так называемых crosses initialization?

Править:
Я знаю, что должен использовать скобки для определения объема r но я хочу знать, почему, например, почему не-POD не мог быть определен в операторе переключения мультислучая.

Спасибо.

81
задан toddsundsted 18 June 2013 в 13:06
поделиться

4 ответа

Версия с 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;
};

Стандарт говорит (6.7 / 3):

Можно выполнить передачу в блок, но не таким образом, чтобы обойти объявления с инициализацией. Программа, которая перескакивает из точки, где локальная переменная с автоматической продолжительностью хранения не находится в области видимости, к точке, где она находится в области видимости, плохо сформирована, если только переменная не имеет тип POD (3.9) и объявлена ​​без инициализатора (8.5).

94
ответ дан 24 November 2019 в 09:39
поделиться

Вы должны заключить содержимое case в скобки, чтобы дать ему область видимости, таким образом вы можете объявить внутри него локальные переменные:

switch(i) {
    case 1:
        {
            // int r = x + y; -- OK
            int r = 1; // Failed to Compile
            cout << r;
        }
        break;
    case 2:
        ...
        break;
};
35
ответ дан 24 November 2019 в 09:39
поделиться

Можно передать в блок, но не каким-либо образом это обходит объявления с инициализацией. Программа, которая перескакивает из точки, в которой локальная переменная с автоматической продолжительностью хранения не находится в области видимости, к точке, где она находится в области видимости, является некорректной, если только переменная не имеет тип POD и не объявлена ​​без инициализатора.

[Example: Code:

void f()
{
  // ...
  goto lx;    // ill-formed: jump into scope of `a'
  // ...
 ly:
    X a = 1;
  // ...
 lx:
   goto ly;    // ok, jump implies destructor
 // call for `a' followed by construction
 // again immediately following label ly
}

--end example]

Переход от условия оператора switch к метке case считается скачком в этом отношении.

3
ответ дан 24 November 2019 в 09:39
поделиться

Я предлагаю вам продвигать вашу переменную r перед оператором switch . Если вы хотите использовать переменную в блоках case (или с тем же именем переменной, но разными способами использования), определите ее перед оператором switch:

#include <iostream>
using namespace std;

int main()
{
    int x, y, i;
    cin >> x >> y >> i;
// Define the variable before the switch.
    int r;
    switch(i) {
        case 1:
            r = x + y
            cout << r;
            break;
        case 2:
            r = x - y;
            cout << r;
            break;
    };
}

Одним из преимуществ является то, что компилятор не имеет для выполнения локального выделения (также известного как отправка в стек) в каждом блоке .

Недостатком этого подхода является то, что случаи «попадают» в другие случаи (т.е. без использования break ), поскольку переменная будет иметь предыдущее значение.

0
ответ дан 24 November 2019 в 09:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: