goto 누출 변수를 사용합니까? : void f() {

goto소멸자와 사물을 호출하지 않고 코드 비트를 건너 뛰는 것이 사실 입니까?

예 :

void f() {
   int x = 0;
   goto lol;
}

int main() {
   f();
lol:
   return 0;
}

x유출 되지 않습니까?



답변

경고 : 이 답변은 C ++ 에만 해당됩니다 . 규칙은 C에서 상당히 다릅니다.


x유출 되지 않습니까?

아니, 절대 아닙니다.

gotoC ++의 기본 제공 범위 지정 메커니즘을 재정의 할 수있는 저수준 구조라는 신화입니다 . (무엇이든간에 longjmp이것에 취약 할 수 있습니다.)

레이블 ( case레이블 포함 )을 사용 하여 “나쁜”작업을 수행하지 못하도록 방지하는 다음 메커니즘을 고려하십시오 .


1. 라벨 범위

함수를 건너 뛸 수 없습니다.

void f() {
   int x = 0;
   goto lol;
}

int main() {
   f();
lol:
   return 0;
}

// error: label 'lol' used but not defined

[n3290: 6.1/1]:[..] 레이블의 범위는 레이블이 표시되는 기능입니다. [..]


2. 객체 초기화

객체 초기화를 건너 뛸 수 없습니다.

int main() {
   goto lol;
   int x = 0;
lol:
   return 0;
}

// error: jump to label ‘lol’
// error:   from here
// error:   crosses initialization of ‘int x’

당신이 이동하면 다시 개체 초기화를 통해 다음 개체의 이전 “인스턴스”파괴 :

struct T {
   T() { cout << "*T"; }
  ~T() { cout << "~T"; }
};

int main() {
   int x = 0;

  lol:
   T t;
   if (x++ < 5)
     goto lol;
}

// Output: *T~T*T~T*T~T*T~T*T~T*T~T

[n3290: 6.6/2]:[..] 루프 외부, 블록 외부 또는 자동 저장 기간이있는 초기화 된 변수를 지나서 이전에는 전송 된 지점에서 범위 내에 있지만 전송 된 지점이 아닌 자동 저장 기간이있는 객체의 파괴가 포함됩니다. . [..]

명시 적으로 초기화되지 않은 경우에도 개체의 범위로 이동할 수 없습니다.

int main() {
   goto lol;
   {
      std::string x;
lol:
      x = "";
   }
}

// error: jump to label ‘lol’
// error:   from here
// error:   crosses initialization of ‘std::string x’

… “복잡한”구성이 필요하지 않기 때문에 언어가 처리 할 수있는 특정 종류의 객체를 제외하고 :

int main() {
   goto lol;
   {
      int x;
lol:
      x = 0;
   }
}

// OK

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


3. 다른 개체의 범위에 따라 점프

마찬가지로 자동 저장 기간 이있는goto 개체 는 범위 벗어나도 “누출” 되지 않습니다 .

struct T {
   T() { cout << "*T"; }
  ~T() { cout << "~T"; }
};

int main() {
   {
      T t;
      goto lol;
   }

lol:
   return 0;
}

// *T~T

[n3290: 6.6/2]:스코프에서 빠져 나가면 (하지만 완료되면) 해당 스코프에서 생성 된 자동 저장 기간 (3.7.3)이있는 객체는 생성의 역순으로 파괴됩니다. [..]


결론

위의 메커니즘 goto은 언어를 깨뜨리지 않도록합니다.

물론, 이것은 자동으로 의미하지 않는다 당신 사용 “해야” goto주어진 문제 만은 않습니다 이 거의 믿을 수있는 일반적인 신화의 리드 사람들로 “악”으로하지 않습니다 것을 의미한다.


답변