C 전처리기 매크로에 전처리기 지시사항이 포함되는 것이 가능합니까?
저는 다음과 같은 것을 하고 싶습니다.
#define print_max(TYPE) \
# ifdef TYPE##_MAX \
printf("%lld\n", TYPE##_MAX); \
# endif
print_max(INT);
이제.#ifdef
함수 매크로에서 볼 수 있는 한 중첩된 전처리기 지시문은 허용되지 않습니다.무슨 생각 있어요?
업데이트: 그래서 이것은 불가능한 것 같습니다.런타임에 확인하는 해킹도 달성할 수 없는 것 같습니다.그래서 저는 다음과 같이 생각합니다.
#ifndef BLAH_MAX
# define BLAH_MAX 0
#endif
# etc... for each type I'm interested in
#define print_max(TYPE) \
if (TYPE##_MAX) \
printf("%lld\n", TYPE##_MAX);
print_max(INT);
print_max(BLAH);
Boost Preprocessor(부스트가 C++ 라이브러리임에도 불구하고 C++뿐만 아니라 C에서도 작동함) 라이브러리를 통해 이러한 작업을 수행할 수 있습니다.허용되지 않는 매크로 내에서 #ifdef를 사용하는 대신 파일을 여러 번 포함하고 매번 다른 매크로를 정의하여 파일이 #ifdef를 사용할 수 있도록 도와줍니다.
다음 코드는 max.c에 저장된 경우 파일 상단의 MAXES #defin에 나열된 각 단어에 대해 원하는 작업을 수행해야 합니다.그러나 _MAX 값 중 하나라도 부동 소수점이면 전처리기가 부동 소수점을 처리할 수 없으므로 작동하지 않습니다.
(Boost Processor는 편리한 도구이지만, 간단하지는 않습니다. 이 방법이 복사 및 붙여넣기에 비해 개선되었는지 여부를 결정할 수 있습니다.)
#define MAXES (SHRT)(INT)(LONG)(PATH)(DOESNT_EXIST)
#if !BOOST_PP_IS_ITERATING
/* This portion of the file (from here to #else) is the "main" file */
#include <values.h>
#include <stdio.h>
#include <boost/preprocessor.hpp>
/* Define a function print_maxes that iterates over the bottom portion of this
* file for each word in MAXES */
#define BOOST_PP_FILENAME_1 "max.c"
#define BOOST_PP_ITERATION_LIMITS (0,BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(MAXES)))
void print_maxes(void) {
#include BOOST_PP_ITERATE()
}
int main(int argc, char *argv[])
{
print_maxes();
}
#else
/* This portion of the file is evaluated multiple times, with
* BOOST_PP_ITERATION() resolving to a different number every time */
/* Use BOOST_PP_ITERATION() to look up the current word in MAXES */
#define CURRENT BOOST_PP_SEQ_ELEM(BOOST_PP_ITERATION(), MAXES)
#define CURRENT_MAX BOOST_PP_CAT(CURRENT, _MAX)
#if CURRENT_MAX
printf("The max of " BOOST_PP_STRINGIZE(CURRENT) " is %lld\n", (long long) CURRENT_MAX);
#else
printf("The max of " BOOST_PP_STRINGIZE(CURRENT) " is undefined\n");
#endif
#undef CURRENT
#undef CURRENT_MAX
#endif
저도 해본 적 있어요.문제는.#
매크로 매개 변수를 문자열화하기 위해 이미 예약되어 있습니다.에 있는 것처럼 전처리기 토큰으로 구문 분석되지 않습니다.#
정의를 내리다
제가 가진 유일한 해결책은 커닝입니다. 정의 집합으로 _XXX_MAX를 가진 유형의 목록을 만든 후 사용하는 것입니다.저는 전처리기에서 자동화된 방식으로 리스트를 만드는 방법을 몰라서 노력하지 않습니다.리스트가 너무 길지 않고 너무 집중적으로 유지되지 않을 것이라는 가정입니다.
#define PRINT_MAX(type) printf("%lld\n", _TYPE##_MAX);
#define HAVE_MAX(type) _TYPE##_MAX // not sure if this works
/* a repetitious block of code that I cannot factor out - this is the cheat */
#ifdef HAVE_MAX(INT)
#define PRINT_INT_MAX PRINT_MAX(INT)
#endif
#ifdef HAVE_MAX(LONG)
#define PRINT_LONG_MAX PRINT_MAX(LONG)
#endif
/* end of cheat */
#define print_max(type) PRINT_##TYPE##_MAX
#ifdef에서 ## 연산자가 허용되지 않는 경우는 아니라고 생각합니다.나는 이것을.
#define _print_max(TYPE) \
#ifdef TYPE \
printf("%lld\n", _TYPE); \
#endif
#define print_max(TYPE) _print_max(MAX##_TYPE)
void main()
{
print_max(INT)
}
그리고 그것은 여전히 작동하지 않았습니다(#ifdef TYPE을 좋아하지 않았습니다.문제는 #ifdef가 #defin 인수가 아닌 #defined 기호만 받아들인다는 것입니다.그것들은 서로 다른 두 가지입니다.
템플릿과 달리 전처리기는 turing-complete가 아닙니다.#ifdef
매크로 내부는 불가능합니다.당신의 유일한 해결책은 당신이 단지 전화만 하도록 하는 것입니다.print_max
일치하는 유형에 대해_MAX
INT_MAX
않을 때 줄 컴파일러는 그들이 그렇지 않을 때 당신에게 분명 말해 줄 것입니다.
이렇게 하기엔 쉬운 방법이 없습니다.가장 가까운 방법은 다음과 같은 IFDEF 매크로를 #정의하는 것입니다.
#undef IFDEF_INT_MAX
#ifdef INT_MAX
#define IFDEF_INT_MAX(X) X
#else
#define IFDEF_INT_MAX(X)
#endif
#undef IFDEF_BLAH_MAX
#ifdef BLAH_MAX
#define IFDEF_BLAH_MAX(X) X
#else
#define IFDEF_BLAH_MAX(X)
#endif
:
많은 파일이 필요하기 때문에(여러 곳에서 유용할 수도 있기 때문에), 이 모든 파일을 자신의 헤더 파일 'ifdefs'에 고정하는 것이 매우 합리적입니다.필요할 때 언제든지 포함할 수 있는 h'.관심 매크로 목록에서 ifdef.h를 재생성하는 스크립트를 작성할 수도 있습니다.
그러면 당신의 코드는
#include "ifdefs.h"
#define print_max(TYPE) \
IFDEF_##TYPE##_MAX( printf("%lld\n", TYPE##_MAX); )
print_max(INT);
print_max(BLAH);
적분값에만 관심이 있고 2의 보어와 8비트 바이트를 사용하여 하드웨어를 가정하는 한:
// Of course all this MAX/MIN stuff assumes 2's compilment, with 8-bit bytes...
#define LARGEST_INTEGRAL_TYPE long long
/* This will evaluate to TRUE for an unsigned type, and FALSE for a signed
* type. We use 'signed char' since it should be the smallest signed type
* (which will sign-extend up to <type>'s size) vs. possibly overflowing if
* going in the other direction (from a larger type to a smaller one).
*/
#define ISUNSIGNED(type) (((type) ((signed char) -1)) > (type) 0)
/* We must test for the "signed-ness" of <type> to determine how to calculate
* the minimum/maximum value.
*
* e.g., If a typedef'ed type name is passed in that is actually an unsigned
* type:
*
* typedef unsigned int Oid;
* MAXIMUM_(Oid);
*/
#define MINIMUM_(type) ((type) (ISUNSIGNED(type) ? MINIMUM_UNSIGNED_(type) \
: MINIMUM_SIGNED_( type)))
#define MAXIMUM_(type) ((type) (ISUNSIGNED(type) ? MAXIMUM_UNSIGNED_(type) \
: MAXIMUM_SIGNED_( type)))
/* Minumum unsigned value; zero, by definition -- we really only have this
* macro for symmetry.
*/
#define MINIMUM_UNSIGNED_(type) ((type) 0)
// Maximum unsigned value; all 1's.
#define MAXIMUM_UNSIGNED_(type) \
((~((unsigned LARGEST_INTEGRAL_TYPE) 0)) \
>> ((sizeof(LARGEST_INTEGRAL_TYPE) - sizeof(type)) * 8))
/* Minimum signed value; a 1 in the most-significant bit.
*
* We use LARGEST_INTEGRAL_TYPE as our base type for the initial bit-shift
* because we should never overflow (i.e., <type> should always be the same
* size or smaller than LARGEST_INTEGRAL_TYPE).
*/
#define MINIMUM_SIGNED_(type) \
((type) \
((signed LARGEST_INTEGRAL_TYPE) \
(~((unsigned LARGEST_INTEGRAL_TYPE) 0x0) << ((sizeof(type) * 8) - 1))))
// Maximum signed value; 0 in most-significant bit; remaining bits all 1's.
#define MAXIMUM_SIGNED_(type) (~MINIMUM_SIGNED_(type))
언급URL : https://stackoverflow.com/questions/301711/is-it-possible-for-c-preprocessor-macros-to-contain-preprocessor-directives
'it-source' 카테고리의 다른 글
git diff -- patientity는 무엇을 위한 것일까요? (0) | 2023.10.18 |
---|---|
지도 내에서 비동기 함수를 호출하는 가장 좋은 방법은? (0) | 2023.10.18 |
장고 모델:부울 필드의 기본값이 Maria에서 설정되지 않았습니다.DB (0) | 2023.10.18 |
다중 컬럼 ASC 및 DESC별 MySQL 주문 (0) | 2023.10.18 |
WooCommerce Billing 양식에 사용자 정의 필드를 추가하시겠습니까? (0) | 2023.10.18 |