C에서는 언제 asserts를 사용해야 합니까?
저는 C에 함수를 작성하고 있습니다.스타일상 오류 코드를 반환하는 것과 비교하여 assert를 사용하는 것이 좋습니다.함수가 두 개의 숫자를 나누고 있다고 가정해 보겠습니다.나눗셈을 0이 아니라고 주장해야 합니까 아니면 오류 코드를 반환해야 합니까?가능하다면 그 차이를 명확히 하기 위해 더 많은 예를 제시해 주시기 바랍니다.
assert프로세스를 중단하지만 프로그램이 컴파일될 때 No-op으로 전환됩니다.-DNDEBUG그래서 그것은 다소 조잡한 디버깅 도구이며 그 이상은 아닙니다.▁use만 해야 합니다.assert예를 들어 알고리즘의 불변성이나 사후 조건을 위반하지만 입력 유효성 검사(라이브러리가 아닌 경우)를 위해 "있을 수 없는" 상황을 확인합니다.클라이언트의 잘못된 입력을 감지하면 친절하게 오류 코드를 반환합니다.
의 예assert그럴 수도 있습니다. 믿을 수 없을 정도로 똑똑한 정렬 알고리즘을 구현했는데 정말 정렬되는지 확인하려고 합니다.정렬 기능은 "그냥 작동"하기 때문에 값을 반환하지 않기 때문에 API를 변경하지 않고 오류 반환을 추가할 수 없습니다.
void sort(int *a, size_t n)
{
recursive_super_duper_sort(a, 0, n);
assert(is_sorted(a, n));
}
static bool is_sorted(int const *a, size_t n)
{
for (size_t i=0; i<n-1; i++)
if (a[i] > a[i+1])
return false;
return true;
}
때, 여러분은 로 이런 입니다.assert임시 디버깅 도구로 유용합니다.
오류 코드가 런타임 동작을 나타냅니다.어설션은 개발자가 프로그램 논리에 대한 가정이 실제로 사실이라고 주장할 수 있도록 해주는 디버깅 도구입니다.
응용 프로그램이 전혀 다른 두 가지입니다.
오류 코드는 정상적인 프로그램 흐름의 일부입니다.어설션은 디버깅 전용이며 어설션이 트리거되면 프로그램이 올바르게 작성되지 않았음을 의미합니다.
일반적으로 asserts는 프로그래머(즉, 사용자)가 프로그램을 실제 사용자에게 릴리스하기 전에 논리/프로그래밍 오류를 찾는 것입니다.런타임 입력 오류를 탐지하는 데 Asserts를 사용하면 안 됩니다. 오류 코드를 사용하십시오.
이것은 정말 취향의 문제입니다.제 의견은 이렇습니다.
경험의 법칙: 주장 실패는 항상 프로그램의 버그입니다.
용사를 합니다.assert호출자가 인수가 올바른지 확인하고 다른 동작이 호출자의 버그임을 나타내려면 함수 매개 변수를 확인합니다.0으로 나누는 것은 IMO의 아주 좋은 예입니다.
호출자가 호출하기 전에 인수가 올바른지 확인할 수 없을 것으로 예상되는 경우 오류 코드를 사용합니다.예를 들어, 사전에 인수를 확인하는 것은 계산 비용이 매우 많이 들 수 있습니다.
사용 안 함assert사용자 입력을 확인합니다.
일반적인 지혜는 assert()를 사용하여 코드를 디버깅하고 "불가능한" 일이 발생했을 때 경고하는 것입니다.이 "경고"는 프로그램을 종료하는 형식을 취합니다.
Jim Coplien(일반 C++ 구루이자 SCRUM 트레이너)이 배포된 코드에서 당신의 주장을 남기는 것을 옹호하는 것을 들었습니다.(말도 안 되는 소리인 거 알아요...)이것은 특히 신뢰성이 높은 서버 코드를 위한 것이었습니다.그 이유는 서버가 "불가능한" 상태에 있는 것을 용인하는 것보다 장애가 발생하여 다른 노드가 인계하도록 하는 것이 더 낫다는 것입니다.
(물론, 실패를 추적하고 분석합니다.버그가 있거나 잘못된 가정이 있다는 뜻입니다.)
첫째번.assert<assert.h>될 수 헤더비예수있다니습컴일파할활여화를성를하사용예▁with(▁compiling▁can▁header다일▁begcc -DNDEBUG 비활성화됩니다 및 이진의 "프로덕션" 버전에 대해 비활성화되는 경우도 있습니다.
둘째, 리눅스 man page에서 언급한 바와 같이,
The purpose of this macro is to help the programmer find bugs in his
program. The message "assertion failed in file foo.c, function
do_bar(), line 1287" is of no help at all to a user.
따라서 주장은 버그가 있는 상황에서만 실패해야 합니다.예외적이거나 오류가 발생한 경우에는 다른 작업을 수행해야 합니다.
도구 컴파일러는 ""를 사용할 수 .assert your ion 에코최적화다니합서드를▁-다▁to니.
에서,quotient 당신은 수함, 함할수를 사용할 입니다.assert전체 (이름을 짓는 가 있을 도 있습니다. , 만이전프안에서램그로그체한확, 당신은제 0고야다신합니다아어니수가아약도마있다니습수짓될것러는나말이게이다르함그면러수의이을름당신의그▁(▁if이▁make▁different,▁(,▁functionis▁divbut▁your▁theor▁should▁to▁you▁sense)quotient_by_non_zero 수 한다면, 인 메시지, ), 즉치인메지시적명요외, 만예예외드세그, 것을약한다고있날어이신것이▁it▁).,▁make▁(▁exception▁if▁message요▁fatal▁ai만세드▁you,즉▁an▁could로▁that▁happen▁consider▁it예외(예,)외,시메지,그.longjmpC), 오류 코드 등입니다.
C는 예외를 지원하지 않기 때문에 오류 코드를 반환하는 것 외에는 실제 옵션이 없습니다.한 C 실한패 Cassert()으로 의결과가 됩니다.abort()그 과정을 파괴하는 것으로 불리게 됩니다.이는 표준 오류 처리와 비교할 수 없습니다.
소수점 에는 부소수연사수있다니습을 할 수 .NaN오류 조건을 표시합니다.정수 연산의 경우 오류 코드가 유일한 옵션입니다.
프로그램이 계속할 수 없는 상황을 충족할 경우 어설션을 사용합니다.주장은 '계약'이며 저는 OS와의 '계약' 및 상황 '지연의 위험'으로 사용합니다.
예외를 에뮬레이트하기 위해 GOTO 'ERRORLABEL'을 사용하고 정리 기능을 실행한 후 정리를 종료할 수 있습니다.
여기 제가 어제 쓴 주장의 실제 예가 있습니다.
두 개의 병렬 어레이를 사용했습니다. 이 어레이를a그리고.b그리고 나는 인덱스를 실행하려고 했습니다.i부터 a그리고 나서 무언가를 하라.a[i]그리고.b[i] 하만만더적요이소들에 .b에 있어서보다a는 내코에배경위있것입을다니반이계열에 배열 경계 이 있을 입니다.b하지만 코드의 다른 부분은 크기를 유지하도록 되어 있습니다.a그리고.b ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠa그리고.b평등했습니다.
크기는 같아야 합니다. 하지만 크기가 동일하지 않다면 배열 끝 이상으로 읽으려고 할 때 발생하는 정의되지 않은 동작에 이상하게 실패하는 것이 아니라 그 이유를 알려주는 어설션에서 코드가 실패하기를 원합니다.b좀 더 작았다면.
assert프로그래머가 절대 일어나서는 안 된다고 믿는 오류를 잡는 것이지만, 일어날 수도 있습니다.
그것이 우리에게 도움이 되는 이유와 실행 중인 것을 봅시다.
우리는 우리의 동물이 개인지 고양이인지 테스트하기 위해 통제문이 있는 기능을 설계했습니다.우리의 코드는 오직 개와 고양이만 다루고 프로그래머로서, 우리는 other 문은 절대 실행되지 않을 것이라고 믿습니다.그러나 알 수 없는 오류(우연한 초기화 및 할당, 감지되지 않은 오버플로 등)로 인해 당사의 설계에도 불구하고 실행될 수 있습니다.
void isDogOrCat(T_animal x){
if(isDog(x)){
printf("Woof\n");
}
else if(isCat(x)){
printf("Meow\n");
}
else{
assert(false);
}
}
오류가 발생하면 즉시 실패한 주장을 가리키며 결과적으로 디버그를 시도하는 것은 쉬운 일입니다.이를 다음과 비교해 보십시오.
if(isDog(x)){
printf("Woof\n");
}
else{
printf("Meow\n");
}
만약 벌레가 여기에 미끄러져 들어온다면, 당신은 훨씬 더 큰 문제에 처하게 될 것입니다.출력 때문에 고양이를 넘겨주는 것이라고 생각할 수 있지만, 모르는 사이에 설계된 범위를 잘못 벗어난 변수를 처리하고 있습니다!
((으)로 할 수 else if(isCat(x)) else하지만 그 경우, 두 문 모두 실행되지 않고 함수가 아무것도 출력하지 않습니다 - 다시 말하지만, 우리의 설계에 반대합니다.)
언급URL : https://stackoverflow.com/questions/8114008/when-should-we-use-asserts-in-c
'programing' 카테고리의 다른 글
| 데이터베이스 연결 테스트 (0) | 2023.07.30 |
|---|---|
| Kotlin에서 Spring 매개변수화된 유형 참조 인스턴스(instance) 작성 (0) | 2023.07.30 |
| 윈도우즈 7의 PowerShell: 일반 사용자를 위한 실행 정책 설정 (0) | 2023.07.30 |
| NSNumber를 사용하여 통화 입력 형식 지정스위프트의 포맷터 (0) | 2023.07.30 |
| 부트스트랩 4의 class="mb-0"은 무엇입니까? (0) | 2023.07.30 |