자체 중괄호 안의 For 루프


117

이 for 루프 레이아웃을 보았습니다.

#include <iostream>
int main()
{
    {
        for (int i = 0; i != 10; ++i)
        {
            std::cout << "delete i->second;" << std::endl;
        }
    }

    {
        for (size_t i = 0; i < 20; ++i)
        {
            std::cout << "delete m_indices[i];" << std::endl;
        }
    }
    return 0;
}

이 여분의 교정기 층이 무엇인지 궁금합니다. 이것은 우리 코드베이스에 몇 번 나타납니다.


47
그들은 당신이 게시 니펫 코드에서 완전히 불필요한 것
EdChum

25
이 코드에 어떤 컴파일러가 사용 되었습니까? 특히 VS 6이 사용 되었습니까?
UKMonkey

5
@EdNorman 이제 편집하면 훨씬 더 명확합니다. 정답은 UKMonkey에서 제공 한 것 같습니다. 최신 C ++ 컴파일러를 사용하면 중괄호를 간단히 삭제할 수 있습니다.
Jabberwocky

8
또는, 생성 할 수있는 코드 (단지 랩소디와 그립에 오는 한숨을 내 쉬었다 사람)
Mawg는 분석 재개 모니카 말한다

4
한 가지 가능한 이유는 코드에 OpenMP 병렬 지시문이있는 경우 (또는 향후 사용할 예정인 경우)입니다.
jamesqf

답변:


286

옛날 옛적에, 여러 달 전에 VS6가 존재했고 인기가있었습니다. 그러나 여러 C ++ 표준을 따르지 못했습니다. 표준이 공식적으로 발표되기 직전 (같은 해에) 발표 되었기 때문에 당시에는 합리적이었습니다. 그러나 내가 아는 한 표준 초안을 고수했습니다.

초안과 공식 표준 사이에 변경된 표준 중 하나는 첫 번째 섹션에서 만든 for 루프 변수의 수명입니다. 컴파일에 실패하는 다음 코드로 이어지는

{
    for (int i=0; i<1; ++i){}
    for (int i=0; i<2; ++i){}
}

i두 번째 for 루프에 의해 재정의 되었기 때문 입니다.

다른 컴파일러들도이 버그를 겪었습니다. VS6 버전은 표준이 출시 된 후 몇 년 동안 Visual Studio의 유일한 버전 이었지만이 특정 문제에 대한 업데이트를 출시하지 않았기 때문에 강조합니다. 더 큰 영향을 미쳤음을 의미합니다.

이에 대한 해결책은 전체 for 루프를 사용자가 보여준대로 자체 범위로 강제하는 것입니다.


49
@bolov를 확인하기 위해 VS6을 찾을 필요가 없습니다. VS2015에서 "For 루프 범위의 강제 준수"를 "아니요"로 설정하고 ;-)
alain

5
@alain "옵션 'ZC : forScope-'는 사용되지 않으며 이후 릴리스에서 제거 될 것입니다"문제없이 컴파일 ... 나는 슬프다
bolov

7
버전 2.7 이전의 GCC도이 동작을 나타 냈습니다. docs.freebsd.org/info/g++FAQ/g++FAQ.info.for_scope.html
Jeremy

5
@Damon VS6가 처음 출시되었을 때가 아니 었습니다. 그러나 표준이 변경되었을 때이를 준수하는 업데이트는 출시되지 않았습니다. VS6는 표준이 변경된 후에도 몇 년 동안 인기를 유지했습니다.
UKMonkey

7
이것이 오래된 마이크로 소프트 컴파일러의 죄 때문이라고 생각하는 것은 가짜입니다. 이 동작은 실제로 C ++ 표준 초안의 기능이었으며 많은 컴파일러가이를 수행했습니다 (Microsoft 컴파일러뿐만 아니라). 메모리에서 첫 번째 C ++ 표준이 비준되기 약 3 년 전에 변수를 루프에 로컬로 만들기 위해 1995 년에 초안에서 변경되었습니다. 따라서 1996 년 이전의 대부분의 C ++ 컴파일러는 이런 방식으로 작동했습니다.
피터

15

{}범위를 작성하고 당신이 범위에 일부 변수를 정의하는 경우는 외부에서 액세스 할 수 없습니다. 그러나 for이미 그 범위를 만듭니다. 그래서

{for(int i = 0; i < count; ++i){}} 

와 같다

for(int i = 0; i < count; ++i){}

하지만 그들 사이에 무언가를 정의하면 차이가 있습니다

{int a = 0; for(int i = 0; i < count; ++i){}}

이 예에서는 a외부 범위에서 액세스 할 수 없습니다.


2

귀하의 특정 예에는 이유가 없습니다.

때로는 변수에 대한 범위를 만들고 싶을 수 있습니다.

float average;
// ...

{
int sum = 0;
for (int i = 0; i < count; ++i)
{
   sum += v[i];
}
average = (float)sum / count;
}

// use average
// sum not in scope here

그러나 나는 이것이 반 패턴이라고 본다. 일반적으로이 작업을 수행 for해야하는 경우 자체 기능 이 있어야합니다.


좋습니다. 자체 기능에 있어야한다고 생각한다면 (최소한 오버 헤드 만 추가 할 수 있지만 거기에 가지 않을 것입니다) 가상의 질문입니다. 스위치 케이스에 대한 특정 로컬 범위? 추가 스코프를 추가하는 것은 (물론 함수도 마찬가지입니다) (예를 들어 별도의 함수가 나쁜 생각이라고 생각하지 않습니다) 불필요하지만 다른 경우에는 다음과 같은 경우에도 그렇게 간단하지 않습니다. 다른 방법이 있습니다.
Pryftan

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.