What are the signs of crosses initialization?

后端 未结 4 1117
谎友^
谎友^ 2020-11-28 03:28

Consider the following code:

#include 
using namespace std;

int main()
{
    int x, y, i;
    cin >> x >> y >> i;
    swit         


        
相关标签:
4条回答
  • 2020-11-28 03:52

    The version with int r = x + y; won't compile either.

    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;
    };
    

    The Standard says (6.7/3):

    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).

    0 讨论(0)
  • 2020-11-28 04:00

    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 and is declared without an initializer.

    [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]
    

    The transfer from the condition of a switch statement to a case label is considered a jump in this respect.

    0 讨论(0)
  • 2020-11-28 04:03

    You should put the contents of the case in brackets to give it scope, that way you can declare local variables inside it:

    switch(i) {
        case 1:
            {
                // int r = x + y; -- OK
                int r = 1; // Failed to Compile
                cout << r;
            }
            break;
        case 2:
            ...
            break;
    };
    
    0 讨论(0)
  • 2020-11-28 04:09

    I suggest you promote your r variable before the switch statement. If you want to use a variable across the case blocks, (or the same variable name but different usages), define it before the switch statement:

    #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;
        };
    }
    

    One of the benefits is that the compiler does not have to perform local allocation (a.k.a. pushing onto the stack) in each case block.

    A drawback to this approach is when cases "fall" into other cases (i.e. without using break), as the variable will have a previous value.

    0 讨论(0)
提交回复
热议问题