Development Tip

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

yourdevel 2020. 10. 7. 21:18
반응형

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


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

#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를 염두에두고 작성되었다고 생각합니다. 아마도 그것과 관련이 있습니까?


정말, 정말 초기 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)

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

int foo PROTOTYPE((int bar));

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

int foo(int bar);

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

int foo();

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

Some libraries still do this; if you look in tcpd.h (if you have it available), you'll see:

/* 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

This explains it well.

As for the double parentheses, __P(arg1, arg2) would give a syntax error (passing too many arguments to the macro), while __P((arg1, arg2)) would be fine (just one enclosed in parentheses).

This is similar to __extension__((...)) in GNU C. In non-GNU compilers, simply #define __extension__(unused) to have semi-portable code, as just one "argument" is given, wrapped in parentheses.

참고URL : https://stackoverflow.com/questions/57779123/whats-the-point-of-a-prototype-macro-that-merely-expands-to-its-arguments

반응형