C 라이브러리가 같은 이름의 매크로와 함수를 사용하는 이유는 무엇입니까?


20

PJ Plauger의 'The Standard C Library'를 읽고 있습니다. 이 책은 라이브러리 사용 방법뿐만 아니라 구현 방법도 설명합니다.

ctype.h섹션을 읽었으며 헤더에서 함수는 매크로 및 함수로 선언됩니다. 예를 들어

int isdigit(int);

뿐만 아니라

#define isdigit(c) (_Ctype[(int)(c)] & _DI)

두 가지를 모두 사용하는 이유를 모르겠습니다.

또한 자신의 사용자 정의 ctype헤더와 구현 을 다시 만들려고 하면 매크로를 제거하면 (정의를 주석 처리) 성공적으로 컴파일 할 수 있습니다.

이 측면은이 책에서 실제로 설명되지 않았습니다. 누군가 설명해 주시겠습니까?


C 표준에는 컴파일러가이를 매크로로 구현하도록 강요하는 것이 없습니다. 매크로는 C에 인라인이 없었던 옛날의 잔류 물일 가능성이 높습니다. 스마트 컴파일러는 필요한 경우 명시적인 인라인 키워드없이 해당 함수를 인라인 할 수 있어야합니다. 따라서 함수와 유사한 매크로는 컴파일러를 만들 때 뛰어난 사람이 컴파일러를 구현했기 때문에 존재합니다.

답변:


23

매크로는 함수 호출을 포함하지 않기 때문에 (상상적으로) 더 효율적입니다. 포인터 오프셋 조회 만 포함하므로보다 쉽게 ​​최적화 할 수 있습니다.

함수 호출은 프로그램이 매크로 정의없이 컴파일 된 경우에도 – 다른 헤더로 컴파일되었거나 소스 파일 내부의 악성 선언으로 컴파일 된 경우에도 동일한 라이브러리에 대한 링크를 허용합니다. 예를 들어, 매크로 가없는 누군가의 "개선 된"ctype.h 버전의 컴파일러 가있는 경우, 함수는 런타임에 여전히 사용됩니다.

우리가 표준을 보면 :

7.1.4 라이브러리 함수 사용

헤더에 선언 된 함수는 헤더에 정의 된 함수와 유사한 매크로로 추가로 구현 될 수 있으므로 헤더가 포함되어있을 때 라이브러리 함수가 명시 적으로 선언 된 경우 아래에 표시된 기술 중 하나를 사용하여 선언이되지 않도록 할 수 있습니다 이러한 매크로의 영향을받습니다. 함수의 매크로 정의는 함수의 이름을 괄호로 묶어 로컬로 억제 할 수 있습니다. 이름 뒤에 매크로 함수 이름의 확장을 나타내는 왼쪽 괄호가 붙지 않기 때문입니다. 동일한 구문상의 이유로, 매크로로 정의 된 경우에도 라이브러리 함수의 주소를 사용할 수 있습니다.

즉, 다음과 같이 쓰는 경우 :

int b = (isdigit)(c);

또는

int (*f)(int) = &isdigit;
int b = f(c);

그런 다음 매크로가 아닌 실제 기능을 호출합니다. 합법적으로 작성할 수도 있습니다.

#undef isdigit
int b = isdigit(c);

또는 ( #include <ctype.h>직접 또는 전이가 없는 소스 파일에서 ) :

extern int isdigit(int);
int b = isdigit(c);

매크로 정의없이 프로그램을 어떻게 컴파일 할 수 있습니까?
user619818

extern int isdigit(int)예를 들어 @ user619818을 사용 합니다.
ecatmur

그냥 분명히, 당신은 사용자가 #include <whatever>가 없지만 대신 int isdigit (int); 구현 파일 맨 위에. 알겠습니다. 답장을 제대로 읽으십시오.
user619818

호출 가능한 함수 (인라인 매크로 코드와 비교)를 사용하면 파이썬 및 펄과 같은 다른 언어도 이러한 함수와 인터페이스 할 수 있습니다
technosaurus
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.