programing

C 프리프로세서: #warning으로 매크로를 전개합니다.

prostudy 2022. 6. 18. 09:18
반응형

C 프리프로세서: #warning으로 매크로를 전개합니다.

#warning 명령어로 매크로 값(매크로 확장)을 인쇄하고 싶습니다.

예를 들어 코드의 경우:

#define AAA 17
#warning AAA = ???

원하는 컴파일 시간 출력은 다음과 같습니다.

warning: AAA = 17

어떤 용도로 사용합니까?또는 코드를 확대하려면 어떻게 해야 합니까?

디렉티브는 디렉티브로 사용할 수 있습니다.#pragma message

예:

#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)

#define AAA 123
#pragma message "content of AAA: " STR(AAA)

int main() { return 0; }

출력은 다음과 같습니다.

$ gcc test.c
test.c:5:9: note: #pragma message: content of AAA: 123
 #pragma message("content of AAA: " STR(AAA))
         ^

참조용:

정말로 경고를 발하고 싶은 경우는, 다음의 조작도 가능합니다.다만, C99 가 유효하게 되어 있는 것에 의해서 다릅니다(gcc 4.8.2 이후에서는 동작합니다만, 이전 버전에서는 테스트되지 않습니다).

#define N 77

#define __STRINGIFY(TEXT) #TEXT
#define __WARNING(TEXT) __STRINGIFY(GCC warning TEXT)
#define WARNING(VALUE) __WARNING(__STRINGIFY(N = VALUE))

#if N == 77
_Pragma (WARNING(N))
#endif

#warning은 표준 C가 아니기 때문에 권장하지 않습니다.게다가, 경고하고 싶지만 오류를 던지지 않는 것은 무엇입니까?경고는 일반적으로 컴파일러가 완전히 위험한 행동을 할 때 사용하는 것으로, C 표준에서는 허용되고 있습니다.일반 응용 프로그램에는 이러한 사례가 없습니다. 결함 없이 컴파일하거나 아예 컴파일하지 않는 것이 좋습니다.따라서 비표준 #경고가 아닌 표준 #error를 사용합니다.

프리프로세서 정의의 실제 내용은 입력할 수 없습니다.다음과 같은 것으로 충분합니다.

#if (AAA < SOMETHING) && (AAA > SOMETHING_ELSE)
  #error AAA is bad.
#endif

프로그래머에게 이 정도면 충분하다고 생각합니다.단, 보다 자세한 내용을 알고 싶은 경우 최신 C 컴파일러를 사용하는 경우에는 static_assert를 사용할 수 있습니다.그러면 원하는 것에 가까운 것을 얻을 수 있습니다.

#include <assert.h>

#define xstr(s) str(s)
#define str(s) #s
#define err_msg(x) #x " is " xstr(x)

#define AAA 17

static_assert(AAA != 17, err_msg(AAA));

이 매크로 메시지에서는 AAA가 17로 출력됩니다.이러한 매크로의 동작에 대해서는, 여기를 참조해 주세요.

static_assert가 C99에 포함되었는지 C11에 포함되었는지 확실하지 않습니다.GCC 확장을 사용하여 활성화해야 할 수 있습니다.

Makefile이 원하는 정의를 포함하는 로컬 generated.h 파일을 생성하는 경우가 많습니다.

생성되었습니다.h: 파일 만들기echo > generated.h "// WARNING: 생성된 파일입니다.대신 Makefile 변경"date >> generated.h '+/'는 %Y-%m-%d %H:%M:%S'echo >> generated.h "#if AAA == AAA_bad"echo >> generated.h "# warning \"AAA = $(AAA_bad)\"echo >> generated.h "#endif"

#include에 대한 요구가 생성되었습니다.h"는 명백하다.

여기서는 어떤 복잡함도 스핀할 수 있지만, 그 이상이면 Makefiles가 난잡할 수 있으므로 그 복잡함을 다른 스크립트에 넣는 것이 좋습니다.약간의 상상력으로 작은 입력으로 많은 수의 테스트를 생성하는 루프를 만들 수 있습니다.

generated.h 타깃이 Makefile에 의존하도록 하는 것은 타겟의 명령이 변경되었을 때 generated.h를 다시 만들기 위해 중요합니다.별도로 생성된 경우.sh 의존성 목록에 있는 스크립트.

면책사항: 실제로 테스트한 적이 없습니다.

다른 간단한 방법은 특히 Makefile 프로젝트(Linux, u-boot, qemu 등)를 다룰 때 파일의 사전 처리된 결과를 볼 수 있습니다.
예를들면,

사전 처리된 파일을 표시하다arch/arm64/kernel/head.S,
할 수 있다arch/arm64/kernel/head.s. (작은 s)

사전 처리된 파일을 표시하다foo/bar/baz.c,
할 수 있다foo/bar/baz.i

매크로가 모두 최종값까지 확장됩니다.

언급URL : https://stackoverflow.com/questions/12637392/c-preprocessor-expand-macro-in-a-warning

반응형