문제

예를 들어 다음과 같은 것입니다.

#define definer(x) #define #x?
도움이 되었습니까?

해결책

구문이 유효하지 않지만 질문에 대한 답은 기술적으로 그렇습니다. 그러나 코드를 읽을 수없고 인재 할 수없는 불쾌한 트릭으로 만 달성 할 수 있습니다.

또한보십시오: http://www.ioccc.org/years.html#1995_vanschnitz 그리고 http://www.ioccc.org/years.html#2004_vik2

다른 팁

아니, 당신은 그렇게 할 수 없습니다.
파운드 (#) 기호는 정의에서 다른 의미를 갖습니다. 그것은 - 이것이 논쟁이라면 그것을 인용하여 문자열로 만드십시오.

C 전 처리기 지침을 중첩 할 수 없습니다. 운 좋게도 거의 필요하지 않습니다. 실제로 그런 종류의 힘이 필요하다면 코드를 C 컴파일러로 나눠주기 전에 실행하는 다른 전처리업자와 거의 더 나을 것입니다. 예를 들어:

sed 's/@CUSTOMER@/J. Random Person/' foo.c.in > foo.c
cc foo.c

또 다른 유용한 트릭은 속임수를 단일 헤더 파일로 분리하는 것입니다.이 파일은 스스로 작성하는 프로그램에 의해 생성됩니다.

./generate-trickery --greet 'J. Random Person' > foo.h

foo.h는 다음과 같이 보일 곳입니다.

#define GREET(x) ("J. Random Person greets you, " #x)

이것을 makefile 또는 다른 자동화와 함께 묶으면 매우 원활하며 개발을 많이하지 않을 것입니다.

아니, 당신은 그렇게 할 수 없습니다.

하나의 매크로를 다른 매크로로 참조 할 수 있지만 한 매크로를 다른 매크로로 정의 할 수는 없습니다.

약간 다른 것을 수행하기 위해 여러 번 호출 할 수있는 전처리 코드 세그먼트를 작성하려는 경우 코드를 단일로 분리하는 것입니다. .h 그때 파일 #include 여러번. 아이디어는 매번 당신이 있다는 것입니다 #include "루틴을 호출"하는 파일 - 먼저 "인수를 통과"합니다. #define포함 된 파일이 참조하는 특정 사전 처리기 상수.

내가 이것을 유용한 곳 중 하나는 "스마트"열거 (I/O에 유용한) 형식 (I/O에 유용한)으로 변환 할 수있는 "스마트"열거를 생성하는 것입니다. 당신은 a를 만듭니다 .h 예를 들어있는 파일

ENUMVAL(foo)
ENUMVAL(bar)
ENUMVAL(baz)

그리고 나중에 #include 이 파일은 두 번 : 한 번 어디에 ENUMVAL() 생성하는 방식으로 정의됩니다. enum 선언, 그리고 언제 ENUMVAL() 문자열 크기의 이름을 생성하는 방식으로 정의됩니다. 이렇게하면 실제 토큰 목록을 두 번 이상 지정할 필요가 없습니다.

#define definer(x) #define #x?

#x는 x의 문자열입니다. 문자열 토큰을 #define 할 수 없습니다. (#define "foo") 식별자 여야합니다. a-za-z0-9 _]* 토큰.

캔트 Nest #Define은 그와 비슷합니다. #define에서 #define을 가질 수 없습니다.

~할 수 있다 #if 내부에 #가 있습니다. #IF 블록이 있습니다.

#ifdef FOO

#ifdef BAR
 ...
#else // BAR
 ...
#endif // BAR

#else // FOO
 ...
#endif //FOO

#IF 매크로에서 사용할 수있는 표현식에 대해서도 다소 제한적입니다. 그러나 때때로 그 일을 할 수 있습니다. 예를 들어:

        /* Use CONCATENATE_4_AGAIN to expand the arguments to CONCATENATE_4 */
#define CONCATENATE_4(      a,b,c,d)  CONCATENATE_4_AGAIN(a,b,c,d)
#define CONCATENATE_4_AGAIN(a,b,c,d)  a ## b ## c ## d

    /* Creates a typedef that's legal/illegal depending on EXPRESSION.       *
     * Note that IDENTIFIER_TEXT is limited to "[a-zA-Z0-9_]*".              *
     * (This may be replaced by static_assert() in future revisions of C++.) */
#define STATIC_ASSERT( EXPRESSION, IDENTIFIER_TEXT)                     \
  typedef char CONCATENATE_4( static_assert____,      IDENTIFIER_TEXT,  \
                              ____failed_at_line____, __LINE__ )        \
            [ (EXPRESSION) ? 1 : -1 ]

다음과 같은 것

STATIC_ASSERT( sizeof(int1) == 1, sizeof_int1_equal_1 );

(예, 알고 있습니다 #포함u003Cstdint.h>. 그것은 단지 예입니다.)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top