왜 매크로가 함수가 아닌 어설트일까요?
수업시간에 선생님이 그런 질문을 하셨는데, 왜 기능이 아니라 매크로인지 궁금했어요.
간단한 설명은 표준이 다음을 요구한다는 것입니다.assert
매크로로서 C99 표준 초안을 보면(C11 표준 초안에서도 섹션이 동일하다고 말할 수 있습니다) 섹션.7.2
Diagnostics 패러그래프 2는 다음과 같습니다.
아사트 매크로는 실제 기능이 아닌 매크로로 구현되어야 한다.실제 함수에 액세스하기 위해 매크로 정의가 억제된 경우 동작은 정의되지 않습니다.
왜 이것이 필요한가? 국제표준의 근거-프로그래밍 언어-C에 제시된 근거는 다음과 같다.
진정한 함수로 어설트 하는 것은 어렵거나 불가능할 수 있기 때문에 매크로 형태로 제한됩니다.
별로 도움이 되지는 않지만, 그 이유를 다른 요구 사항에서 알 수 있습니다.으로 7.2
1항은 다음과 같다.
[...NDEBUG]가 포함된 원본 파일의 지점에서 매크로 이름으로 정의된 경우 아사트 매크로는 다음과 같이 정의됩니다.
#define assert(ignore) ((void)0)
아사트 매크로는 포함될 때마다 NDEBUG의 현재 상태에 따라 재정의됩니다.
이는 비용이 많이 들 수 있는 체크 비용을 부담해야 하는 릴리스 모드에서 어설션을 쉽게 끌 수 있는 방법을 제공하므로 중요합니다.
를 사용해야 입니다.__FILE__
,__LINE__
★★★★★★★★★★★★★★★★★」__func__
7.2.1.1
다음과 같은 아사트 매크로:
[...] 아사트 매크로는 실패한 특정 호출에 대한 정보를 구현 정의 형식으로 표준 오류 스트림에 각각 전처리 매크로 __FILE_ 및 __LINE__ 및 식별자 __func__)165)의 값입니다.다음으로 Abort 함수를 호출합니다.
서 각주 「」를 참조해당됩니다.165
라고 말합니다
작성된 메시지는 다음과 같은 형식이 될 수 있습니다.
Assertion failed: expression, function abc, file xyz, line nnn.
으로, 「」가하게 됩니다.__FILE__
etc...는 적절한 장소에서 평가되며, Joachim이 지적한 바와 같이 매크로가 생성되는 메시지에 원래 표현을 삽입할 수 있습니다.
에서는 C++의 을 'C++'로 .cassert
는 header의 header와 .assert.h
C: standrd C의 헤더:
내용은 Standard C 라이브러리 헤더와 동일합니다.
다음 항목도 참조하십시오.ISO C 7.2
왜 (void)0일까요?
「」를 사용하는가?(void)0
무무른른른른른른른른른른른른른른른? 수 , 첫 절의 .첫 번째 섹션의 아사트 개요는 다음과 같습니다.7.2.1.1
:
void assert(scalar expression);
그리고 이렇게 써있네요.
아사트 매크로는 진단 테스트를 프로그램에 넣습니다.이 매크로는 무효 표현식으로 확장됩니다.
그 the (void)0
공허한 표정으로 끝날 필요성과 일치합니다.
요건이 했을 때, 그 은, 예를 들면, 「아니다」, 「아니다」의 등, 않은 가 있을 수 .assert
디버깅 모드에서는 허용되지 않는 릴리스 모드에서 예를 들어 플레인(plain)을 사용하면assert
했을 경우, 「이러다」가 생성될 이 있습니다.expression result unused
경고합니다.코멘트대로 복합문을 사용하는 것에 대해서는, C 멀티 라인 매크로:do/while(0) vs scope block으로부터, 바람직하지 않은 영향이 있는 것을 알 수 있습니다.
왜 매크로가 함수가 아닌 어설트일까요?
이는 DEBUG 모드로 컴파일되어야 하며 RELEASE 모드로 컴파일해서는 안 되기 때문입니다.
- 할 수 (파일을 캡처할 수 있습니다).
__FILE__
__LINE__
) - 「 」를할 수 있습니다.
assert
도 하지 아도 to to(((((((((((((((((((((((((((((((((:((void)0)
)를 릴리즈
포함 시점에서 NDEBUG라는 이름의 매크로가 이미 정의되어 있는 경우 이 매크로는 비활성화됩니다.이것에 의해, 프로그램을 디버깅 하는 동안, 코더가 소스코드에 필요한 만큼의 아사트 콜을 포함시켜, 다음과 같은 행만을 포함한 실가동 버전의 모든 콜을 디세블로 할 수 있습니다.
#define NDEBUG
에 「Code」를 전에, 「Code」의 선두에 「Code의 선두에는, 「Code」를 붙입니다.<assert.h>
.
따라서 이 매크로는 프로그램이 디버깅 단계를 종료한 후 일반적으로 비활성화되므로 사용자 오류나 런타임 오류가 아닌 프로그래밍 오류를 캡처하도록 설계되었습니다.
이 기능을 함수로 하면 일부 함수 호출이 증가하고 릴리스 모드에서 이러한 모든 어사트를 제어할 수 없습니다.
는, 「」로 합니다._FILE__
,__LINE__
★★★★★★★★★★★★★★★★★」__func__
주장하다그 발신자 회선이나 발신자 함수의 회선이 아닙니다.
일부 주장은 호출 비용이 많이 들 수 있습니다.방금 고성능 매트릭스 반전 루틴을 작성하고 건전성 검사를 추가했습니다.
assert(is_identity(matrix * inverse))
끝까지.매트릭스가 꽤 크네요assert
함수이기 때문에 계산을 하는 데 많은 시간이 걸릴 수 있습니다.디버깅을 하지 않으면 시간을 낭비하고 싶지 않습니다.
혹은 비교적 저렴한 주장일 수도 있지만, 내부 루프에서 호출되는 매우 짧은 함수에 포함되어 있습니다.아니면 다른 비슷한 상황일 수도 있어요
assert
대신 매크로를 사용하면 어설션이 꺼졌을 때 계산을 완전히 제거할 수 있습니다.
언급URL : https://stackoverflow.com/questions/25285557/why-is-assert-a-macro-and-not-a-function
'programing' 카테고리의 다른 글
const는 C/C++에서 어떤 최적화를 제공합니까? (0) | 2022.08.14 |
---|---|
Vuex 스토어 모듈 상태 개체를 비우는 방법 (0) | 2022.08.14 |
C의 2가지 미완성 구현이 있습니까? (0) | 2022.08.13 |
jVisualVM에서의 샘플링과 프로파일링의 차이 (0) | 2022.08.13 |
Java : 스트림의 올바른 문자 집합 인코딩을 확인하는 방법 (0) | 2022.08.13 |