내가 아는 한 인기있는 것은 아니지만 몇 가지 있습니다. 주석을 중첩시키는 데 나쁜 점이 있습니까?
나는 작업중 인 (작은) 언어로 블록 주석을 중첩 할 계획이지만 이것이 나쁜 생각인지 알고 싶습니다.
내가 아는 한 인기있는 것은 아니지만 몇 가지 있습니다. 주석을 중첩시키는 데 나쁜 점이 있습니까?
나는 작업중 인 (작은) 언어로 블록 주석을 중첩 할 계획이지만 이것이 나쁜 생각인지 알고 싶습니다.
답변:
아무도 언급하지 않은 한 가지 사항에 대해 언급하겠습니다. 주석을 중첩하려는 욕구는 종종 프로그래머가 잘못하고 있음을 나타냅니다.
먼저, 프로그래머가 "중첩"또는 "중첩하지 않음"을 볼 수있는 유일한 시간은 프로그래머가 다음과 같은 구조적으로 무언가를 작성할 때입니다.
do_something();
/* comment /* nested comment */ more comment */
do_something_else();
이제 언제 그런 일이 실제로 발생합니까? 분명히 프로그래머는 문자 그대로 위의 스 니펫처럼 보이는 중첩 된 주석을 작성하지 않을 것입니다 ! 아니요, 실제로 주석을 중첩 할 때 (또는 중첩 할 수 있기를 원하는 경우) 다음과 같이 작성하기 때문입니다.
do_something(); /* do a thing */
/* [ajo] 2017-12-03 this turned out to be unnecessary
do_something_else(); /* do another thing */
*/
그리고 이것은 나쁜 것입니다. 이것은 (언어 디자이너로서) 우리가 권장하고 싶은 패턴이 아닙니다! 올바른 위의 코드 조각을 작성하는 방법은 다음과 같습니다
do_something(); /* do a thing */
"잘못된"코드, 잘못된 시작 또는 코드가 코드베이스에 속하지 않습니다. 소스 제어 히스토리에 속합니다. 이상적으로는 시작하기에 잘못된 코드를 작성하지 않아도됩니다. 그리고 잘못된 코드가 거기에 목적을 제공했다면 어떤 이유로 든 유지 보수 관리자에게 코드를 복원하지 말라고 경고함으로써 잘 작성된 의도적 코드 주석에 대한 작업 일 것입니다 . X를 수행하지만 주석 처리 된 일부 오래된 코드를 남겨 두어 "X를 수행하지 않음"을 표현하는 것은 사람들이 X를하지 못하게하는 가장 읽기 쉽고 효과적인 방법이 아닙니다.
이 모든 것은 이전에 들었던 간단한 경험 법칙으로 요약됩니다 . 코드를 주석 처리하지 마십시오. (업집니다이 구절을 검색 하시나요 많은 의 의견 에 계약을 .)
질문하기 전에 : 그렇습니다. C, C # 및 C ++와 같은 언어는 이미 프로그래머에게 큰 코드 블록을 주석 처리하는 다른 도구를 제공합니다 #if 0
. 그러나 이것은 C 전 처리기의 특정 응용 프로그램이며, 그 자체로는 크고 유용한 도구입니다. 언어가 조건부 컴파일을 지원 #if
하지만 아직 지원 하지 않는 것은 실제로 매우 어렵고 특별한 경우 #if 0
입니다.
따라서 우리는 중첩 된 주석이 프로그래머가 코드를 주석 처리 할 때만 관련이 있다는 것을 확인했습니다. 우리는 코드를 주석 처리하는 것이 나쁜 것임을 (많은 숙련 된 프로그래머의 합의를 통해) 확립했습니다.
실로를 완성하려면 언어 디자이너가 좋은 것을 홍보하고 나쁜 것을 억제하는 데 관심이 있음을 인정해야합니다 (다른 모든 것이 동일하다고 가정).
중첩 된 주석의 경우 다른 모든 항목 이 동일합니다. 중첩 된 구문 분석이 구문 /*
분석기에 대해 "어려울 것" 이라고 주장하는 투표가 적은 답변은 무시 해도됩니다. (Nested /*
는 nested보다 어렵지 않으며 (
, 세계의 거의 모든 파서가 이미 처리해야합니다.)
언어 디자이너가 주석을 쉽게 중첩 시키거나 (코드 주석 처리) 어렵게해야합니까? 코드 주석 처리는 나쁜 것임을 상기하십시오.
QED
각주. 중첩 된 주석을 허용하지 않으면
hello /* foo*/bar.txt */ world
오해의 소지가있는 "댓글"입니다.
hello bar.txt */ world
(구문 오류 일 수 있음). 당신이한다면 할 중첩 된 댓글은 허용
hello /* foo/*.txt */ world
오해의 소지가있는 "댓글"입니다.
hello
그러나 주석은 파일 끝까지 계속 열어 둡니다 (이것은 구문 오류 일 것입니다). 따라서 의도하지 않은 구문 오류가 발생하기 쉽습니다. 유일한 차이점은 주석 처리 된 코드 의 의도적 인 반 패턴을 처리하는 방법 입니다.
#if DEAD
는 정식적이고 가장 잘 설계된 예입니다. 많은 언어에서 데드 코드를와 동등한 것으로 감쌀 수 있습니다 if (DEAD)
. 그리고 많은 IDE에서 실제로 죽은 코드를 제거하고 원하는 경우 Ctrl + Z 및 / 또는 버전 제어를 사용하여 다시 가져올 수 있습니다. 텍스트가 많은 데드 코드 인 주석을 남기는 것은 여전히 가독성에 대한 최악의 옵션입니다.
대부분의 구현은 별도의 렉싱 및 구문 분석 단계를 사용하고 렉싱에는 일반 오래된 정규 표현식을 사용합니다. 주석은 공백으로 처리됩니다. 즉, 무시 된 토큰이므로 완전히 렉싱 패스에서 해결해야합니다. 이 방법의 유일한 장점은 구문 분석 속도입니다. 다수의 단점은 구문에 대한 심각한 제한 (예를 들어, 문맥에 독립적 인 고정 된 키워드 세트를 유지해야 할 필요성)을 포함한다.
중첩 된 주석을 처리 할 수있는 어휘 분석기를 만드는 것이 가능합니다. 공백을 먹으면 /*
깊이 카운터를 늘리고을 볼 때 감소 */
시키고 깊이가 0이면 멈출 수 있습니다. 즉, 나는 많은 파서를 수행했으며 주석이 중첩되어야하는 좋은 이유를 찾지 못했습니다.
주석이 중첩 될 수 있다면 단점은 균형을 잡기가 쉽습니다. 멋진 편집기가 없으면 보이지 않는 코드를 보이지 않게 숨길 수 있습니다.
중첩되지 않은 주석의 장점은 다음과 같습니다.
/*
some code
more code
blah blah blah
/**/
첫 줄 (1 줄 편집)을 제거하거나 추가하여 코드에 쉽게 주석을 달거나 넣을 수 있습니다. 물론 코드 자체에 주석이 포함되어 있으면 C ++ 스타일 주석 도 허용 하지 않으면 중단 //
됩니다. 그래서 제가하는 경향이 있습니다.
//
주석도 C99 스타일입니다.
/*$token
. 여기서 identifier
영숫자 토큰은 어디에 있고 주석은입니다 token$*/
. 토크 나이저가 모든 종료 주석 표시에 일치하는 시작 주석 블록에 적합한 토큰이 포함되어 있는지 확인하는 코드를 포함하는 것은 비교적 간단합니다.
중첩 된 블록 주석을 지원하면 구문 분석기가 복잡해 지므로 더 많은 작업이 수행되고 컴파일 시간이 늘어날 수 있습니다. 언어에 필요한 기능은 아니지만 다른 개선 및 최적화에 시간과 노력을 사용하는 것이 좋습니다.
내 생각에 단순성은 항상 디자인하는 데 좋은 것입니다. 기능을 제거하는 것보다 기능을 추가하는 것이 더 쉽다는 점에 유의하십시오. 중첩 된 주석을 허용하고 해당 주석을 사용하는 프로그램이 있으면 호환성을 손상시키지 않으면 서 주석을 제거 할 수 없습니다.
/*/**/
어휘 분석기에서 일반적으로 사용되는 정규 표현식의 풍미가 재귀를 지원하지 않기 때문에 중첩 된 주석은 구문 분석기가 처리해야하는 이유 중 하나입니다. 간단한 것들은 렉서에 의해 공백으로 제거 될 수 있으므로, 그렇게 구현하는 것이 더 간단합니다.
중첩 된 주석은 파서에 대한 추가 작업을 의미합니다. 일반적으로 주석의 시작을 보면 끝 주석 표시까지 모든 것을 무시합니다. 중첩 된 주석을 지원하려면 주석의 텍스트도 구문 분석해야합니다. 그러나 가장 큰 문제는 프로그래머가 중첩 된 모든 주석을 올바르게 닫을 때주의해야하며 그렇지 않으면 컴파일 오류가 발생한다는 것입니다. 컴파일러를 올바르게 구현하는 것은 수행 할 수 있지만 프로그래머로서 중첩 된 주석을 추적하는 것은 오류가 발생하기 쉽고 자극적입니다.