귀환의 요점은 무엇입니까?
[dcl.attr.noreturn] 은 다음 예제를 제공합니다.
[[ noreturn ]] void f() {
throw "error";
// OK
}
그러나 [[noreturn]]
함수의 반환 유형이 이미 있기 때문에 요점을 이해하지 못합니다 void
.
그렇다면 noreturn
속성 의 요점은 무엇 입니까? 어떻게 사용해야합니까?
noreturn 속성은 호출자에게 반환되지 않는 함수에 사용됩니다. 즉, void 함수 (호출자에게 반환-값을 반환하지 않음)를 의미하는 것이 아니라 함수가 완료된 후 제어 흐름이 호출 함수로 반환되지 않는 함수 (예 : 응용 프로그램을 종료하는 함수, 영원히 반복하거나 예와 같이 예외를 throw하십시오).
이것은 컴파일러가 최적화를 수행하고 더 나은 경고를 생성하는 데 사용할 수 있습니다. 예를 들어 f
noreturn 속성이있는 경우 컴파일러는 g()
쓸 때 데드 코드임을 경고 할 수 있습니다 f(); g();
. 마찬가지로 컴파일러는에 대한 호출 후 누락 된 return 문에 대해 경고하지 않습니다 f()
.
noreturn
컴파일러에게 함수가 값을 반환하지 않는다고 알려주지 않습니다. 컴파일러에게 제어 흐름이 호출자에게 반환되지 않음 을 알려줍니다 . 이를 통해 컴파일러는 다양한 최적화를 수행 할 수 있습니다. 호출 주변의 일시적인 상태를 저장 및 복원 할 필요가 없으며 호출을 따르는 코드를 데드 코딩하여 제거 할 수 있습니다.
기능이 완료되지 않았 음을 의미합니다. 다음에 대한 호출 후에 제어 흐름이 명령문에 절대로 도달하지 않습니다 f()
.
void g() {
f();
// unreachable:
std::cout << "No! That's impossible" << std::endl;
}
정보는 컴파일러 / 최적화 프로그램이 다른 방식으로 사용할 수 있습니다. 컴파일러는 위의 코드에 도달 할 수 없다는 경고를 추가 할 수 있으며 g()
연속성을 지원하기 위해 다양한 방법으로 실제 코드를 수정할 수 있습니다 .
이전 답변은 귀환이 무엇인지 정확하게 설명했지만 존재 이유 는 아닙니다 . 나는 "최적화"주석이 주된 목적이라고 생각하지 않습니다. 반환하지 않는 함수는 드물고 보통 최적화 할 필요가 없습니다. 오히려 나는 귀환의 주요 원인은 거짓 양성 경고를 피하는 것이라고 생각합니다. 예를 들어 다음 코드를 고려하십시오.
int f(bool b){
if (b) {
return 7;
} else {
abort();
}
}
abort ()가 "noreturn"으로 표시되지 않은 경우 컴파일러는 f가 예상대로 정수를 리턴하지 않는 경로를 갖는이 코드에 대해 경고했을 수 있습니다. 그러나 abort ()는 반환되지 않기 때문에 코드가 정확하다는 것을 알고 있습니다.
이론적으로 말하면, void
다른 언어 unit
또는 로 불리는 것입니다 top
. 논리적으로 동등한 것은 True 입니다. 모든 값은 합법적으로 캐스트 될 수 있습니다 void
(모든 유형은의 하위 유형입니다 void
). "우주"세트로 생각하십시오. 세계의 모든 값 에 공통된 연산 이 없으므로 type 값에 유효한 연산이 없습니다 void
. 다른 방식으로 말하면, 어떤 것이 우주 세트에 속한다고 말하면 어떤 정보도 제공하지 않습니다. 이미 알고 있습니다. 따라서 다음은 소리입니다.
(void)5;
(void)foo(17); // whatever foo(17) does
그러나 아래 과제는 그렇지 않습니다.
void raise();
void f(int y) {
int x = y!=0 ? 100/y : raise(); // raise() returns void, so what should x be?
cout << x << endl;
}
[[noreturn]]
반면에, 때로는라고 empty
, Nothing
, Bottom
또는 Bot
과의 논리와 동일 거짓 . 값이 전혀 없으며이 유형의 표현식은 모든 유형으로 캐스트 될 수 있습니다 (예 : 하위 유형). 이것은 빈 세트입니다. 누군가가 "foo () 표현식의 값이 빈 세트에 속한다" 고 말하면 이 정보 는 매우 유익합니다.이 표현식은 정상적인 실행을 완료하지 못할 것입니다. 중단, 던지거나 매달려 있습니다. 와 정반대입니다 void
.
따라서 다음은 의미가 없습니다 (의사 C ++, noreturn
일류 C ++ 유형이 아니기 때문에 )
void foo();
(noreturn)5; // obviously a lie; the expression 5 does "return"
(noreturn)foo(); // foo() returns void, and therefore returns
그러나 아래의 할당 throw
은 컴파일러가 반환하지 않는 것으로 이해 되기 때문에 완벽하게 합법적입니다 .
void f(int y) {
int x = y!=0 ? 100/y : throw exception();
cout << x << endl;
}
In a perfect world, you could use noreturn
as the return value for the function raise()
above:
noreturn raise() { throw exception(); }
...
int x = y!=0 ? 100/y : raise();
Sadly C++ does not allow it, probably for practical reasons. Instead it gives you the ability to use [[ noreturn ]]
attribute which helps guiding compiler optimizations and warnings.
참고URL : https://stackoverflow.com/questions/10538291/what-is-the-point-of-noreturn
'Programing' 카테고리의 다른 글
튜플에 가변 항목이 포함될 수있는 이유는 무엇입니까? (0) | 2020.05.24 |
---|---|
TypeError : 문자열 형식을 지정하는 동안 모든 인수가 변환되는 것은 아닙니다 (0) | 2020.05.23 |
섹션 대 기사 HTML5 (0) | 2020.05.23 |
cURL을 사용하여 파일 내용을 본문 엔터티로 보내는 방법 (0) | 2020.05.23 |
Django에서 다 대다 필드를 선택적으로 만들려면 어떻게해야합니까? (0) | 2020.05.23 |