[assert] 어설 션은 언제 프로덕션 코드에 있어야합니까? [닫은]

comp.lang.c ++. moderated에서 C ++에서 기본적으로 디버그 빌드에만 존재하는 어설 션이 프로덕션 코드에 유지되어야하는지 여부에 대한 논의가 진행되고 있습니다.

물론, 여기 내 질문은 각각의 프로젝트는 고유 하지 너무 많은 여부를 주장 보관해야 하지만, 어떤 경우에 이 추천 / 안 좋은 생각이다.

주장으로, 나는 의미한다 :

  • 거짓 인 경우 소프트웨어의 버그를 나타내는 조건을 테스트하는 런타임 검사.
  • 프로그램이 정지되는 메커니즘 (정말 최소한의 정리 작업 후).

나는 반드시 C 또는 C ++에 대해 이야기하지는 않습니다.

내 자신의 의견은 프로그래머이지만 데이터를 소유하지 않는 경우 (대부분의 상용 데스크톱 응용 프로그램의 경우) 실패한 어설 션에 버그가 표시되어 계속하지 말아야한다는 점입니다. 버그로 인해 사용자 데이터가 손상 될 위험이 있습니다. 이렇게하면 발송하기 전에 테스트를 강하게 수행하고 버그를보다 눈에 잘 띄게하여 쉽게 찾아 수정할 수 있습니다.

당신의 의견 / 경험은 무엇입니까?

건배,

관련 질문을 여기에서보십시오


응답 및 업데이트

그레이엄,

어설 션은 오류이며 순수하고 단순하므로 하나처럼 처리해야합니다. 릴리스 모드에서 오류를 처리해야하므로 어설 션이 실제로 필요하지 않습니다.

그래서 어설 션에 대해 이야기 할 때 “버그”라는 단어를 선호합니다. 훨씬 명확 해집니다. 나에게 “오류”라는 단어는 너무 모호하다. 누락 된 파일은 버그가 아니라 오류이며 프로그램에서 처리해야합니다. 널 포인터를 역 참조하려고하는 것은 버그이며 프로그램은 나쁜 치즈 냄새가 나는 것을 인정해야합니다.

따라서 어설 션을 사용하여 포인터를 테스트해야하지만 정상적인 오류 처리 코드가있는 파일이 있어야합니다.


주제를 약간 벗어 났지만 토론에서 중요한 점입니다.

실패로 어설 션이 실패 할 때 어설 션이 디버거에 침입하는 이유는 무엇입니까? 그러나 코드가 완전히 제어 할 수없는 파일이 존재하지 않는 많은 이유가 있습니다 : 읽기 / 쓰기 권한, 디스크 가득 참, USB 장치 연결 해제 등. 제어 할 수 없기 때문에 어설 션이 있다고 생각합니다. 그것을 처리하는 올바른 방법이 아닙니다.


도마,

예, Code Complete가 있으며 해당 특정 조언에 강력히 동의하지 않는다고 말해야합니다.

사용자 지정 메모리 할당자가 나사를 조이고 다른 개체에서 여전히 사용중인 메모리 덩어리를 0으로 만듭니다. 나는이 객체가 정기적으로 역 참조하는 포인터를 제로화하고 변하지 않는 것 중 하나는이 포인터가 결코 null이 아니라는 것입니다. 그런 식으로 유지되도록 몇 가지 주장이 있습니다. 포인터가 갑자기 null 인 경우 어떻게해야합니까? 당신은 주위에 if ()가 작동하기를 바라고 있습니까?

여기서 제품 코드에 대해 이야기하고 있으므로 디버거를 중단하고 로컬 상태를 검사하지 않습니다. 이것은 사용자 컴퓨터의 실제 버그입니다.



답변

주장은 구식이 아닌 주석입니다. 어떤 이론적 상태가 의도되고 어떤 상태가 발생하지 않아야하는지 문서화합니다. 코드가 변경되어 상태 변경이 허용되면 개발자에게 곧 알리고 어설 션을 업데이트해야합니다.


답변

Steve McConnell의 Code Complete를 인용하겠습니다. 어설 션 섹션은 8.2입니다.

일반적으로 사용자는 프로덕션 코드에서 어설 션 메시지를 보지 않기를 원합니다. 어설 션은 주로 개발 및 유지 관리 중에 사용됩니다. 어설 션은 일반적으로 개발시 코드로 컴파일되고 프로덕션 코드에서 컴파일됩니다.

그러나 같은 섹션의 뒷부분에서이 조언이 제공됩니다.

매우 강력한 코드를 위해 어쨌든 오류를 주장하고 처리하십시오.

성능이 문제가되지 않는 한 어설 션은 그대로두고 메시지를 표시하지 말고 로그 파일에 쓰십시오. 나는 조언도 Code Complete에 있다고 생각하지만 지금은 찾지 못했습니다.


답변

프로그램이 꺼진 상태에서 프로그램이 상당히 빠르게 실행되는 것을 측정하지 않은 경우 프로덕션 코드에서 어설 션을 켜 두십시오.

그것이 더 효율적임을 증명할 가치가 없다면, 퍼포먼스 도박에 대한 선명도를 희생 할 가치가 없습니다. “-Steve McConnell 1993

http://c2.com/cgi/wiki?ShipWithAssertionsOn


답변

프로덕션 환경에서 어설 션을 남길 생각이 있다면 아마도 그것들에 대해 잘못 생각하고있을 것입니다. 어설 션의 핵심은 솔루션의 일부가 아니므로 프로덕션 환경에서 해제 할 수 있다는 것입니다. 그것들은 당신의 가정이 올바른지 확인하는 데 사용되는 개발 도구입니다. 그러나 생산에 들어가면 이미 가정에 대한 확신이 있어야합니다.

즉, 프로덕션 환경에서 어설 션을 설정하는 경우가 있습니다. 프로덕션 환경에서 재현 가능한 버그가 발생하여 테스트 환경에서 어려움을 겪고 있다면 어설 션이 설정된 상태에서 버그를 재현하는 것이 도움이 될 수 있습니다. 유용한 정보를 제공하는지 확인하십시오.

더 흥미로운 질문은 다음과 같습니다. 테스트 단계에서 어설 션을 언제 해제합니까?


답변

주장이해야 결코 생산 코드를 유지하지 않습니다. 특정 어설 션이 프로덕션 코드에서 유용 할 것 같으면 어설 션이 아니어야합니다. 런타임 오류 검사, 즉 다음과 같이 코딩되어야합니다 if( condition != expected ) throw exception.

‘어설 션 (assertion)’이라는 용어는 “개발 시간 전용 점검을 의미합니다. 현장에서는 수행 되지 않는 합니다.

주장이 현장에 올 수 있다고 생각하기 시작하면 주어진 주장이 실제로 가치가 있는지 궁금해하는 것과 같은 다른 위험한 생각을 시작하게 될 것입니다. 가치가없는 주장은 없습니다. “내가 이것을 주장해야합니까?” “내가 주장하는 것을 잊어 버린 것이 있습니까?”


답변

프로파일 링에서 어설 션으로 인해 성능 문제가 발생하지 않는 한 프로덕션 릴리스에서도 그대로 유지되어야한다고 말합니다.

그러나 이것은 또한 어설 션 오류를 다소 정상적으로 처리해야한다고 생각합니다. 예를 들어, 프로그램을 종료하거나 중단하지 않고 개발자에게 문제를 (자동으로)보고하는 옵션이있는 일반 유형의 대화 상자가 나타납니다. 또한 실제로 허용하지만 원치 않는 것을 좋아하거나 고려하지 않는 조건에 대해서는 어설 션을 사용하지 않도록주의해야합니다. 이러한 조건은 코드의 다른 부분에서 처리해야합니다.


답변

내 C ++에서는 릴리스 빌드에서 어설 션이 실패하면 예외가 발생한다는 점을 제외하고는 assert (x)와 같은 REQUIRE (x)를 정의합니다.

실패한 어설 션은 버그를 나타내므로 릴리스 빌드에서도 심각하게 처리해야합니다. 내 코드의 성능이 중요한 경우에는 종종 높은 수준의 코드에는 REQUIRE ()를 사용하고 빠르게 실행해야하는 낮은 수준의 코드에는 assert ()를 사용합니다. 또한 실패 조건이 타사에서 작성한 코드에서 전달 된 데이터 또는 파일 손상으로 인해 발생할 수있는 경우 assert 대신 REQUIRE를 사용합니다. 항상 그렇게 할 시간이있는 것은 아닙니다.)

그들은 당신이 그 주장 메시지를 이해하지 못하기 때문에 최종 사용자에게 표시해서는 안된다고 말합니다. 그래서? 최종 사용자는 스크린 샷 또는 오류 메시지 텍스트가 포함 된 전자 메일을 보내 디버깅 할 수 있습니다. 사용자가 단순히 “충돌 됨”이라고 표시하면 해결할 수있는 능력이 떨어집니다. 어설 션 실패 메시지를 인터넷을 통해 자동으로 자신에게 보내는 것이 좋지만 사용자가 인터넷에 액세스 할 수 있고 사용자의 권한을 얻을 수있는 경우에만 작동합니다.