인수로만 확장되는 PROTOTYPE 매크로의 요점은 무엇입니까?


82

포함 된 헤더 파일이 있습니다.

#define PROTOTYPE(s) s

그 요점은 무엇입니까? 입력을 그 자체로 대체하는 것처럼 보입니다.

주변에 다른 지시문이 많이 있지만 정의 된 경우 베어링을 확인한 것으로 보이는 유일한 지시문은 다음과 같습니다 #ifndef PROTOTYPE.. 이 작업을 수행하는 HDF4 헤더 파일의 일부 위치를 찾았습니다 #define PROTOTYPE. 그래서, 그 어느 것도 내 질문을 정말로 명확하게 해주지 않습니다. 여전히 쓸모없는 것 같습니다.

사용 방법은 다음과 같습니다.

CS_RETCODE clientmsg_callback PROTOTYPE((
CS_CONTEXT * context,
CS_CONNECTION *connection,
CS_CLIENTMSG *clientmsg));

이것은 Sybase Open Client를 사용하는 프로젝트의 일부입니다. clientmsg_callback은 나중에 여기에서 사용됩니다.

ct_callback(context, NULL, CS_SET, CS_CLIENTMSG_CB,
                  (CS_VOID *)clientmsg_callback);

여기에서 샘플 프로그램을 시작하겠습니다.

http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc35570.1570/html/clcprgde/clcprgde10.htm

clientmsg_callback은 나중에 구현됩니다. 샘플은 원래 C ++ 대신 C를 염두에두고 작성되었다고 생각합니다. 아마도 그것과 관련이 있습니까?


6
대신 다른 정의를 가질 수있는 근처에 #if/ #ifdef/ #ifndef/ #else지시문이 있습니까? 다른 매크로, 특히 #또는 근처에서 사용하면 차이를 만들 수 ##있습니다. 주석 스타일 일 수 있습니다. 실제로 대답 할 컨텍스트가 충분하지 않습니다.
aschepler

일반적인 대답 : 누군가가 변경하고 싶은 이유가있을 수 있기 때문 PROTOTYPE입니다. 쓸모없는 것처럼 보이는 이상한 정의를 본다면 누군가 편리하게 무언가를 변경하고 싶을 때 잠재적 인 유연성에 대해 생각해보십시오.
Apollys 모니카 지원

답변:


130

정말, 정말 초기 C의 옛날에는 프로토 타입 같은 것이 없었습니다. 함수 인수 목록은 함수의 괄호 뒤에 오는 다음과 같이 :

square(x)
int x;
{
int y = x * x;
return y;
}

물론 요즘에는 인수가 괄호 안에 들어갑니다.

square(int x)
{
int y = x * x;
return y;
}

"누락 된"반환 유형에 유의하십시오. C 함수는 암시 적으로를 반환하는 데 사용되었으며 int다른 반환 유형이 필요한 경우에만 해당 내용을 말해야했습니다.

함수 선언 에는 또 다른 규칙 세트가 있습니다. K & R C (고대 버전)의 함수 선언에는 인수가 없습니다.

int square();

ANSI C의 함수 프로토 타입 에는 인수 목록이 있습니다.

int square(int x);

전환하는 동안 사람들은 이상한 매크로를 사용하여 두 가지 방법으로 컴파일 할 수있었습니다.

int square(PROTOTYPE(int x));

#define PROTOTYPE(s)

첫 번째 버전으로 확장됩니다.

#define PROTOTYPE(s) s

두 번째로 확장됩니다.

질문에있는 코드의 "추가"괄호와 관련하여 인수 목록에 인수가 두 개 이상있을 때 필요합니다. 그것들이 없으면 매크로 호출에는 둘 이상의 인수가 있으므로 하나의 인수로 정의 된 매크로와 일치하지 않습니다.

PROTOTYPE(int x, int y)   // error: too many arguments
PROTOTYPE((int x, int y)) // ok: only one argument (enclosed in parentheses)

10
와. 과거로부터의 폭발. 소프트웨어에서 저의 첫 번째 작업 중 하나는 기존 코드베이스에서 이러한 것들을 제거하는 것이 었습니다. Unix의 한 줄짜리 텍스트 변형 프로그램에 대한 건전한 존경심을 쌓았습니다.
user4581301

15
나는 그것들이 어떻게 작동하는지 이해하지 못한다. 어떻게 #define PROTOTYPE(s)입력 int x;이 바뀌는가 x? 그것은 나에게 빈 문자열로 감싸는 것 같습니다
Ferrybig

3
@Ferrybig-죄송합니다. 혼란 스러웠습니다. 그것은의 프로토 타입 이 방법으로 정의됩니다. K & R C에서 프로토 타입에는 인수가 없었고 ANSI C에서는 우리가 보았던 인수 목록 스타일이 있습니다.
Pete Becker 19 년

1
이 방법은 매크로 zlib.h를 사용하는 zlib 라이브러리 의 헤더 에서도 볼 수 있습니다 OF(). github.com/madler/zlib/blob/master/zlib.h
Paul Belanger

@PaulBelanger 실제 정의는 zconf.h.
SS Anne

16

이와 같은 매크로는 헤더 파일의 프로토 타입에서 다음과 같은 것을 허용하는 데 사용됩니다.

int foo PROTOTYPE((int bar));

ANSI C가 감지되면 ( __STDC__1로 정의 됨) 다음으로 확장됩니다.

int foo(int bar);

ANSI C가 감지되지 않으면 다음으로 확장됩니다.

int foo();

C가 표준화되기 전에 일반적이었습니다.

일부 라이브러리는 여전히이 작업을 수행합니다. 살펴보면 tcpd.h(사용 가능한 경우) 다음이 표시됩니다.

/* someone else may have defined this */
#undef  __P

/* use prototypes if we have an ANSI C compiler or are using C++ */
#if defined(__STDC__) || defined(__cplusplus)
#define __P(args)       args
#else
#define __P(args)       ()
#endif

이것은 그것을 잘 설명합니다.

이중 괄호의 __P(arg1, arg2)경우 구문 오류 (매크로에 너무 많은 인수를 전달 함)가 발생하지만 __P((arg1, arg2))괜찮습니다 (괄호로 묶인 하나만).

이것은 __extension__((...))GNU C에서 와 비슷합니다 . GNU가 아닌 컴파일러에서는 #define __extension__(unused)단지 하나의 "인수"가 괄호로 둘러싸여있는 것처럼 반 이식 가능한 코드를 갖기 만하면 됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.