매크로 정의의 pragma


99

pragma 문을 다른 문과 함께 매크로에 포함하는 방법이 있습니까?

나는 다음과 같은 것을 달성하려고 노력하고 있습니다.

#define DEFINE_DELETE_OBJECT(type)                      \
    void delete_ ## type_(int handle);                  \
    void delete_ ## type(int handle);                                                \
    #pragma weak delete_ ## type_ = delete_ ## type

부스트 솔루션 (웨이브 용으로 저장)이 있으면 괜찮습니다.


5
틀림없이 둘 다 아닙니다. #pragma는 C 또는 C ++ 표준에 의해 정의되지 않았습니다.

전처리 기는 그가 실행하려는 특정 허용 하위 명령이 아닌 경우에도 마찬가지입니다.
Puppy

@DeadMG : C와 C ++ 사이에는 공통적 인 것들이 많이 있습니다. 전처리가 대부분 일반적이지만 사용되는 언어 표준 (C89, C99, C ++ 및 C ++ 0x FCD)에 따라 전처리가 지정되는 방식에 큰 차이가 있습니다.
James McNellis 2010 년

2
@James McNellis : 기술적으로 대부분의 C 프로그램이 C ++로 이식 가능하기 때문에 C ++ 프로그래머가 대부분의 작업을 수행 할 수 없기 때문에 실제로 일반적인 기능을 만들지 않습니다. 두 언어는 실제로 공통점이 많지 않습니다.
Puppy

답변:


114

c99 또는 c ++ 0x를 사용하는 경우 다음과 같이 사용되는 pragma 연산자가 있습니다.

_Pragma("argument")

이는

#pragma argument

매크로에서 사용할 수 있다는 점을 제외하고 (c99 표준의 섹션 6.10.9 또는 c ++ 0x 최종위원회 초안의 16.9 참조)

예를 들면

#define STRINGIFY(a) #a
#define DEFINE_DELETE_OBJECT(type)                      \
    void delete_ ## type ## _(int handle);                  \
    void delete_ ## type(int handle);                   \
    _Pragma( STRINGIFY( weak delete_ ## type ## _ = delete_ ## type) )
DEFINE_DELETE_OBJECT(foo);

에 투입 할 때 gcc -E제공

void delete_foo_(int handle); void delete_foo(int handle);
#pragma weak delete_foo_ = delete_foo
 ;

32
참고로 : MSVC에는 __pragma()전 처리기 연산자가 있습니다. 이는 불행히도 C99의 _Pragma()연산자 와 약간 다릅니다 (C99는 문자열 리터럴, MSVC는 문자열에없는 토큰) : msdn.microsoft.com/en-us/library/d9x1s805 .aspx
Michael Burr

15
@MichaelBurr MSVC는 항상 달라야합니다.
Thomas

5

_Pragma ( "argument")로 할 수있는 한 가지 좋은 점은 다음과 같은 일부 컴파일러 문제를 처리하는 데 사용하는 것입니다.

#ifdef _MSC_VER
#define DUMMY_PRAGMA _Pragma("argument")
#else
#define DUMMY_PRAGMA _Pragma("alt argument")
#endif

0

아니요, 이식 가능한 방법은 없습니다. 다시 말하지만, #pragma를 사용하는 이식 가능한 방법은 전혀 없습니다. 이 때문에 많은 C / C ++ 컴파일러는 pragma와 유사한 작업을 수행하기위한 자체 메서드를 정의하고 종종 매크로에 포함 할 수 있지만 모든 컴파일러에 대해 다른 매크로 정의가 필요합니다. 그 길을 갈 의향이 있다면, 종종 다음과 같은 일을하게됩니다.

#if defined(COMPILER_GCC)
#define Weak_b
#define Weak_e __attribute__((weak))
#elif defined(COMPILER_FOO)
#define Weak_b __Is_Weak
#define Weak_e
#endif

#define DEFINE_DELETE_OBJECT(type)                      \
    Weak_b void delete_ ## type_(int handle) Weak_e;    \
    Weak_b void delete_ ## type(int handle)  Weak_e;    

GCC와 같은 일부 컴파일러는 속성을 유형 서명에 추가로 추가하고 MSC와 같은 일부는 접두사로 추가하기 때문에 정의 Weak_b하고 Weak_e시작 및 끝 브라케팅 구문 으로 정의 하고 싶은 경우가 명확하지 않은 경우 (또는 적어도 MSC를 사용한 지 몇 년이 지났습니다.) 브라케팅 구조를 사용하면 전체 유형 서명을 컴파일러 구조로 전달해야하는 경우에도 항상 작동하는 것을 정의 할 수 있습니다.

물론, 원하는 속성없이 이것을 컴파일러로 이식하려고한다면, 할 수있는 일은 없지만 매크로를 확장하지 않고 코드가 계속 실행되기를 바랍니다. 순전히 경고하거나 pragma를 최적화하는 경우 가능성이 있습니다. 다른 경우에는 그렇게 많지 않습니다.

아, 그리고 실제로 Weak_b와 Weak_e를 매개 변수를 사용하는 매크로로 정의해야한다고 생각하지만,이 예제를 위해 약한 정의를 만드는 방법에 대한 문서를 읽으려고하지 않았습니다. 나는 그것을 독자를위한 연습으로 남겨둔다.


-3

pragma 문을 다른 문과 함께 매크로에 포함하는 방법이 있습니까?

아니요, 전 처리기 문을 전 처리기 문에 넣을 수 없습니다. 그러나 inline함수에 넣을 수 있습니다. 그러나 그것은 C태그를 무력화시킵니다 .


1
인라인 함수에 넣으면 무슨 소용이 있습니까? 전 처리기 지시문은 함수를 인식 할 수있는 것보다 먼저 처리됩니다.

2
C99에는 inline, 대부분의 주요 C89 구현에는 약간의 변형이 있습니다.
Chris Lutz

@Chris 귀하의 의견이 나에게 전달되었다고 가정하면 요점은 무엇입니까?

@Neil-아니요, 죄송합니다. @sbi의 마지막 문장에서 연출했습니다.
Chris Lutz

1
@Chris : 아, inlineC ++에서 빌린 또 다른 C가 있습니다! :)
sbi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.