왜 일부 커널 프로그래머들은 루프 중에 단순 대신 goto를 사용하는가?
C를 배웠을 때 선생님은 하루 종일 "고토 쓰지 마, 나쁜 습관이야, 못생기고 위험해!"라고 말씀하셨어.
일부 는 왜 ""를 합니까?goto
예를 들어, 이 기능에서는 단순한 것으로 대체할 수 있습니다.
while(condition) {}
또는
do {} while(condition);
난 그것을 이해할 수 없다. 고토 대신 ?while
/do
-while
약약면면면면면면면?
이력 컨텍스트:우리는 Dijkstra가 1968년에 Goto Consided Enharious라는 글을 썼다는 것을 기억해야 한다. 그때 많은 프로그래머들은 이 글을goto
구조화된 프로그래밍을 대체하기 위한 것입니다(if
,while
,for
등 ) 。
44년이라는 않습니다.goto
했습니다.구조화된 프로그래밍은 이미 오래 전에 승리했습니다.
케이스 분석:
코드 예는 다음과 같습니다.
SETUP...
again:
COMPUTE SOME VALUES...
if (cmpxchg64(ptr, old_val, val) != old_val)
goto again;
구조화 버전은 다음과 같습니다.
SETUP...
do {
COMPUTE SOME VALUES...
} while (cmpxchg64(ptr, old_val, val) != old_val);
구조화 된 버전을 보면 바로 '루프다'라는 생각이 들어요.가 봤을 때, ★★★★★★★★★★★★★★★★★★★★★★★★.goto
마지막에는 '다시 시도' 케이스가 있는 스트레이트 라인이라고 생각합니다.
goto
에는 둘 다 .SETUP
★★★★★★★★★★★★★★★★★」COMPUTE SOME VALUES
대부분의 경우 제어 흐름은 양쪽을 통과한다는 것을 강조합니다.에는 「」가 붙어 .SETUP
★★★★★★★★★★★★★★★★★」COMPUTE SOME VALUES
이 서로될 수 있음을
여기서의 질문은 코드에 어떤 종류의 강조점을 두느냐는 것입니다.을 비교해보면 '하다'라고 할 수 .goto
'이것'은 다음과 같습니다.
구조화 버전:
if (do_something() != ERR) {
if (do_something2() != ERR) {
if (do_something3() != ERR) {
if (do_something4() != ERR) {
...
Goto 버전:
if (do_something() == ERR) // Straight line
goto error; // |
if (do_something2() == ERR) // |
goto error; // |
if (do_something3() == ERR) // |
goto error; // V
if (do_something4() == ERR) // emphasizes normal control flow
goto error;
생성된 코드는 기본적으로 동일하기 때문에 오목한 부분과 같은 인쇄상의 문제로 생각할 수 있습니다.
이 예에서는 SMP 서포트를 원래 비 SMP 세이프 방식으로 작성된 코드로 리폼하기 위한 것이라고 생각합니다.의 추가goto again;
기능을 재구성하는 것보다 경로가 훨씬 간단하고 덜 침습적입니다.
이 마음에 말할 수 , 이을 피하는 것은합니다.goto
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★goto
사용법예와 은 '사용법'(이 예와 다름)'입니다.goto
는 함수 내에서 전진할 때만 사용되며 후진할 수 없습니다.에서는, 「 구조」가 「루프 구조」가 .goto
필요한 동작을 구현하는 가장 간단하고 명확한 방법입니다(일반적으로 청소 후 오류 발생 시 반환).
매우 좋은 질문입니다.저자만이 확답을 줄 수 있다고 생각합니다.덧붙여 @Izkata의 설명대로 에러 처리에 사용하는 것으로부터 시작되었을지도 모른다고 생각합니다만, 그 후 게이트는 기본적인 루프에도 사용할 수 있게 되었습니다.
에러 처리의 사용법은 시스템 프로그래밍에 있어서 정당한 것이라고 생각합니다.함수는 진행에 따라 점진적으로 메모리를 할당하며 오류가 발생하면 다음과 같이 처리됩니다.goto
그 시점부터 역순으로 자원을 해방하기 위한 적절한 라벨.
따라서 첫 번째 할당 후 오류가 발생하면 마지막 오류 레이블로 이동하여 리소스를 하나만 해방합니다.마찬가지로 마지막 할당 후 오류가 발생하면 첫 번째 오류 라벨로 이동하여 해당 라벨에서 실행되며 기능이 종료될 때까지 모든 리소스가 해방됩니다.이러한 패턴은 특히 코드 수정, Valgrind 및 유닛테스트를 강력히 권장할 경우 오류처리에 주의하여 사용할 필요가 있습니다.그러나 다른 접근법보다 가독성과 유지보수가 용이하다는 것은 논란의 여지가 없다.
사용의 황금률goto
이른바 스파게티 코드를 피하기 위해서입니다.각각에 선을 긋습니다.goto
명세서 및 해당 라벨.선이 교차하는 경우 선을 넘은 것입니다:).이 같은 사용방법goto
는 매우 읽기 어렵고 추적하기 어려운 버그의 일반적인 원인입니다.플로우 제어에 의존하는 BASIC 등의 언어에서 버그를 찾을 수 있기 때문입니다.
심플한 루프를 1개만 하면 선을 넘지 않기 때문에 읽기 쉽고 유지보수가 가능하기 때문에 스타일도 크게 좌우됩니다.단, 질문에서 지적하신 바와 같이 언어 제공 루프 키워드를 사용하면 쉽게 할 수 있기 때문에 사용을 피하는 것이 좋습니다.goto
루프의 경우, 단순히for
,do/while
또는while
건축물은 디자인적으로 더 우아하다.
언급URL : https://stackoverflow.com/questions/13001067/why-do-some-kernel-programmers-use-goto-instead-of-simple-while-loops
'programing' 카테고리의 다른 글
Vuex를 사용하여 API를 호출하는 올바른 방법은 무엇입니까? (0) | 2022.08.17 |
---|---|
Vuex getter의 옵서버에서 값 가져오기 (0) | 2022.08.17 |
nuxt plugins 글로벌 메서드의 typescript 정의에 유형이 있습니까? (0) | 2022.08.11 |
vue 컴포넌트가 있는 브라우저의 뒤로 버튼을 비활성화하려면 어떻게 해야 합니까? (0) | 2022.08.11 |
스토어 데이터가 필요한 API를 깔끔하게 호출하는 방법 (0) | 2022.08.11 |