TL; DR
이니셜 라이저 또는 케이스 내에서 사소하지 않은 개체를 사용하여 변수를 선언 할 수있는 유일한 방법 은 루프 또는 if 문과 같은 자체 범위가있는 다른 제어 구조를 사용하여 블록 범위 를 도입하는 {}
것 입니다.
피투성이 세부 사항
우리는 볼 수있는 경우가 바로되어 제표 표시 등 라벨 와 함께 사용 고토 문 ( 이은으로 덮여 표준 초안 C ++ 6.1 레이블 문 ) 우리는 절에서 볼 수있는 6.7
제 3 많은 경우에 허용되지 않습니다 점프 선언을 통과하는 것이 , 초기화 포함 :
블록으로 전송할 수 있지만 초기화를 통해 선언을 우회하는 방식은 아닙니다. 자동 저장 기간이있는 변수가 범위 내에 있지 않은 지점에서 범위 내에있는 지점으로 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 ;
}
완벽하게 유효합니다 ( 라이브 예제 ). 물론 각 경우에 동일한 변수를 선언하려면 각각 고유 한 범위가 필요하지만 switch 문 외부에서도 동일한 방식으로 작동 하므로 큰 놀라지 않아야합니다.
초기화를 넘어서 점프를 허용하지 않는 이유에 대해서는 약간 다른 문제를 다루지 만 결함 보고서 467 은 자동 변수에 대한 합리적인 사례를 제공 합니다 .
[...] 자동 변수는 명시 적으로 초기화되지 않은 경우 트랩 표현을 포함하여 불확실한 ( "가비지") 값을 가질 수 있습니다. [...]
스위치 내에서 범위 를 여러 경우로 확장하는 경우를 살펴 보는 것이 더 흥미로울 것입니다 . 가장 유명한 예는 다음과 같은 Duff의 장치 일 것입니다 .
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
}
}