Programming

case 문에서 {} 사용.

procodes 2020. 8. 18. 20:26
반응형

case 문에서 {} 사용. 왜?


에서 {사용의 요점은 무엇입니까 ? 일반적으로 명령문 에 몇 줄이 있더라도 모든 줄이 실행됩니다. 이것은 단지 구형 / 최신 컴파일러에 관한 규칙입니까, 아니면 그 뒤에 뭔가가 있습니까?}casecase

int a = 0;
switch (a) {
  case 0:{
    std::cout << "line1\n";
    std::cout << "line2\n";
    break;
  }
}

int a = 0;
switch (a) {
  case 0:
    std::cout << "line1\n";
    std::cout << "line2\n";
    break;
}

{}새로운 블록 나타낸다 범위 .

다음과 같은 매우 인위적인 예를 고려하십시오.

switch (a)
{
    case 42:
        int x = GetSomeValue();
        return a * x;
    case 1337:
        int x = GetSomeOtherValue(); //ERROR
        return a * x;
}

x범위에 이미 정의되어 있기 때문에 컴파일러 오류가 발생 합니다.

이를 자체 하위 범위로 분리 x하면 switch 문 외부에서 선언 할 필요가 없습니다 .

switch (a)
{
    case 42: {
        int x = GetSomeValue();
        return a * x; 
    }
    case 1337: {
        int x = GetSomeOtherValue(); //OK
        return a * x; 
    }
}

TL; DR

이니셜 라이저 또는 케이스 내에서 사소하지 않은 객체를 사용하여 변수를 선언 할 수있는 유일한 방법 루프 또는 if 문과 같은 자체 범위가있는 다른 제어 구조를 사용하여 블록 범위 를 도입하는 {}입니다.

피투성이 세부 사항

우리는 볼 수있는 경우가 바로되어 제표 표시라벨 와 함께 사용 고토 문 ( 이은으로 덮여 표준 초안 C ++ 6.1 레이블 문 ) 우리는 절에서 볼 수있는 6.73 많은 경우에 허용되지 않습니다 점프 선언을 통과하는 것이 , 초기화 포함 :

블록으로 전송할 수 있지만 초기화를 통해 선언을 우회하는 방식은 아닙니다. 자동 저장 기간이있는 변수가 범위 내에 있지 않은 지점에서 범위 내에있는 지점으로 87 을 점프하는 프로그램 은 변수에 스칼라 유형, 사소한 기본 생성자가있는 클래스 유형 및 사소한 소멸자가 없으면 형식이 잘못되었습니다. 이 유형 중 하나의 cv 규정 버전 또는 이전 유형 중 하나의 배열이며 이니셜 라이저없이 선언됩니다 (8.5).

이 예제를 제공합니다.

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
}

여기에는 몇 가지 미묘한 점이 있습니다. 초기화가없는 스칼라 선언건너 뛸 수 있습니다. 예를 들면 다음과 같습니다.

switch( n ) 
{
    int x ;
    //int x  = 10 ; 
    case 0:
      x = 0 ;
      break;
    case 1:
      x = 1 ;
      break;
    default:
      x = 100 ;
      break ;
}

is perfectly valid(live example). Of course if you want to declare the same variable in each case then they will each need their own scope but it works the same way outside of switch statements as well, so that should not be a big surprise.

As for the rationale for not allowing jump past initialization, defect report 467 although covering a slightly different issue provides a reasonable case for automatic variables:

[...]automatic variables, if not explicitly initialized, can have indeterminate (“garbage”) values, including trap representations, [...]

It is probably more interesting to look at the case where you extend a scope within a switch over multiple cases the most famous examples of this is probably Duff's device which would look something like this:

void send( int *to, const int *from, int  count)
{
        int n = (count + 7) / 8;
        switch(count % 8) 
        {
            case 0: do {    *to = *from++;   // <- Scope start
            case 7:         *to = *from++;
            case 6:         *to = *from++;
            case 5:         *to = *from++;
            case 4:         *to = *from++;
            case 3:         *to = *from++;
            case 2:         *to = *from++;
            case 1:         *to = *from++;
                        } while(--n > 0);    // <- Scope end
        }
}

It is a habit that allows you to inject variable declarations with the resulting destructor (or scope conflicts) into case clauses. Another way of looking at it is they are writing for the language they wish they had, where all flow control consists of blocks and not sequences of statements.


Check this a basic compiler restriction and you will start wondering whats happening :

int c;
c=1;

switch(c)
{
    case 1:
    //{
        int *i = new int;
        *i =1;
        cout<<*i;
        break;
    //}

    default : cout<<"def";
}

This will give you an error:

error: jump to case label [-fpermissive]
error:   crosses initialization of ‘int* i’

While this one will not:

int c;
c=1;

switch(c)
{
    case 1:
    {
        int *i = new int;
        *i =1;
        cout<<*i;
        break;
    }

    default : cout<<"def";
}

Using brackets in switch denotes a new block of scope as said by Rotem.

But it can be as well for clarity when you read. To know where the case stops as you might have conditionnal break in it.


The reasons might be:

  1. Readability, it visually enhances each case as a scoped section.
  2. Declaring the a different variables with the same name for several switch cases.
  3. Micro optimizations- scope for a really expensive resource allocated variable that you want to destruct as soon as you leave the scope of the case, or even a more spaghetti scenario of the "GOTO" command usage.

참고URL : https://stackoverflow.com/questions/20031147/using-in-a-case-statement-why

반응형