컴파일 타임에 #define의 값을 어떻게 표시합니까?
내 코드에서 사용중인 Boost 버전을 확인하려고합니다. 나는 이런 식으로하고 싶다 :
#error BOOST_VERSION
그러나 전처리 기는 BOOST_VERSION을 확장하지 않습니다.
나는 프로그램에서 런타임에 그것을 인쇄 할 수 있다는 것을 알고 있으며, 대답을 찾기 위해 전 처리기의 출력을 볼 수 있다는 것을 알고 있습니다. 컴파일 중에이 작업을 수행하는 방법이 유용 할 수 있습니다.
Visual C ++를 사용하는 경우 다음을 사용할 수 있습니다 #pragma message
.
#include <boost/preprocessor/stringize.hpp>
#pragma message("BOOST_VERSION=" BOOST_PP_STRINGIZE(BOOST_VERSION))
편집 : 링크를위한 LB 덕분에
분명히, GCC 동등 물은 (테스트되지 않음)입니다.
#pragma message "BOOST_VERSION=" BOOST_PP_STRINGIZE(BOOST_VERSION)
BOOST_PP_STRINGIZE
C ++에는 탁월한 솔루션으로 보이지만 일반 C에는 적합하지 않습니다.
다음은 GNU CPP에 대한 솔루션입니다.
/* Some test definition here */
#define DEFINED_BUT_NO_VALUE
#define DEFINED_INT 3
#define DEFINED_STR "ABC"
/* definition to expand macro then apply to pragma message */
#define VALUE_TO_STRING(x) #x
#define VALUE(x) VALUE_TO_STRING(x)
#define VAR_NAME_VALUE(var) #var "=" VALUE(var)
/* Some example here */
#pragma message(VAR_NAME_VALUE(NOT_DEFINED))
#pragma message(VAR_NAME_VALUE(DEFINED_BUT_NO_VALUE))
#pragma message(VAR_NAME_VALUE(DEFINED_INT))
#pragma message(VAR_NAME_VALUE(DEFINED_STR))
위의 정의는 다음과 같습니다.
test.c:10:9: note: #pragma message: NOT_DEFINED=NOT_DEFINED
test.c:11:9: note: #pragma message: DEFINED_BUT_NO_VALUE=
test.c:12:9: note: #pragma message: DEFINED_INT=3
test.c:13:9: note: #pragma message: DEFINED_STR="ABC"
들어 "interger로 정의" , "문자열로 정의" 와 "정의되어 있지만 값" 변수는, 그들은 잘 작동하지 않습니다. "정의되지 않은" 변수에 대해서만 원래 변수 이름과 정확히 동일하게 표시됩니다. 익숙해 져야합니다. 그렇지 않으면 누군가 더 나은 솔루션을 제공 할 수 있습니다.
원래 쿼리 이후 오랜 시간이 걸리지 만 여전히 유용 할 수 있습니다.
stringify 연산자 "#"를 사용하여 GCC에서 수행 할 수 있지만 두 단계가 필요합니다.
#define XSTR(x) STR(x)
#define STR(x) #x
매크로의 값은 다음과 같이 표시 될 수 있습니다.
#pragma message "The value of ABC: " XSTR(ABC)
gcc 온라인 문서의 3.4 스트링 화를 참조하십시오.
작동 방식 :
The preprocessor understands quoted strings and handles them differently from normal text. String concatenation is an example of this special treatment. The message pragma requires an argument that is a quoted string. When there is more than one component to the argument then they must all be strings so that string concatenation can be applied. The preprocessor can never assume that an unquoted string should be treated as if it were quoted. If it did then:
#define ABC 123
int n = ABC;
would not compile.
Now consider:
#define ABC abc
#pragma message "The value of ABC is: " ABC
which is equivalent to
#pragma message "The value of ABC is: " abc
This causes a preprocessor warning because abc (unquoted) cannot be concatenated with the preceding string.
Now consider the preprocessor stringize (Which was once called stringification, the links in the documentation have been changed to reflect the revised terminology. (Both terms, incidentally, are equally detestable. The correct term is, of course, stringifaction. Be ready to update your links.)) operator. This acts only on the arguments of a macro and replaces the unexpanded argument with the argument enclosed in double quotes. Thus:
#define STR(x) #x
char *s1 = "abc";
char *s2 = STR(abc);
will assign identical values to s1 and s2. If you run gcc -E you can see this in the output. Perhaps STR would be better named something like ENQUOTE.
This solves the problem of putting quotes around an unquoted item, the problem now is that, if the argument is a macro, the macro will not be expanded. This is why the second macro is needed. XSTR expands its argument, then calls STR to put the expanded value into quotes.
As far as I know '#error' only will print strings, in fact you don't even need to use quotes.
Have you tried writing various purposefully incorrect code using "BOOST_VERSION"? Perhaps something like "blah[BOOST_VERSION] = foo;" will tell you something like "string literal 1.2.1 cannot be used as an array address". It won't be a pretty error message, but at least it'll show you the relevant value. You can play around until you find a compile error that does tell you the value.
Without boost :
define same macro again and compiler HIMSELF will give warning.
From warning you can see location of the previous definition.
vi file of previous definition .
ambarish@axiom:~/cpp$ g++ shiftOper.cpp
shiftOper.cpp:7:1: warning: "LINUX_VERSION_CODE" redefined
shiftOper.cpp:6:1: warning: this is the location of the previous definition
#define LINUX_VERSION_CODE 265216
#define LINUX_VERSION_CODE 666
int main ()
{
}
#define a <::BOOST_VERSION>
#include a
MSVC2015: fatal error C1083: Cannot open include file: '::106200': No such file or directory
Works even if preprocess to file
is enabled, even if invalid tokens are present:
#define a <::'*/`#>
#include a
MSVC2015: fatal error C1083: Cannot open include file: '::'*/`#': No such file or directory
GCC4.x: warning: missing terminating ' character [-Winvalid-pp-token]
#define a <::'*/`#>
In Microsoft C/C++, you can use the built-in _CRT_STRINGIZE()
to print constants. Many of my stdafx.h
files contain some combination of these:
#pragma message("_MSC_VER is " _CRT_STRINGIZE(_MSC_VER))
#pragma message("_MFC_VER is " _CRT_STRINGIZE(_MFC_VER))
#pragma message("_ATL_VER is " _CRT_STRINGIZE(_ATL_VER))
#pragma message("WINVER is " _CRT_STRINGIZE(WINVER))
#pragma message("_WIN32_WINNT is " _CRT_STRINGIZE(_WIN32_WINNT))
#pragma message("_WIN32_IE is " _CRT_STRINGIZE(_WIN32_IE))
#pragma message("NTDDI_VERSION is " _CRT_STRINGIZE(NTDDI_VERSION))
and outputs something like this:
_MSC_VER is 1915
_MFC_VER is 0x0E00
_ATL_VER is 0x0E00
WINVER is 0x0600
_WIN32_WINNT is 0x0600
_WIN32_IE is 0x0700
NTDDI_VERSION is 0x06000000
You could also preprocess the source file and see what the preprocessor value evaluates to.
Are you looking for
#if BOOST_VERSION != "1.2"
#error "Bad version"
#endif
Not great if BOOST_VERSION is a string, like I've assumed, but there may also be individual integers defined for the major, minor and revision numbers.
Looking at the output of the preprocessor is the closest thing to the answer you ask for.
I know you've excluded that (and other ways), but I'm not sure why. You have a specific enough problem to solve, but you have not explained why any of the "normal" methods don't work well for you.
You could write a program that prints out BOOST_VERSION
and compile and run it as part of your build system. Otherwise, I think you're out of luck.
BOOST_VERSION is defined in the boost header file version.hpp.
Take a look at the Boost documentation as well, regarding how you are using the macro:
In reference to BOOST_VERSION
, from http://www.boost.org/doc/libs/1_37_0/libs/config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.boost_helper_macros:
Describes the boost version number in XXYYZZ format such that:
(BOOST_VERSION % 100)
is the sub-minor version,((BOOST_VERSION / 100) %
1000)
is the minor version, and(BOOST_VERSION / 100000)
is the major version.
참고URL : https://stackoverflow.com/questions/1562074/how-do-i-show-the-value-of-a-define-at-compile-time
'IT story' 카테고리의 다른 글
Java 인터페이스의 선택적 메소드 (0) | 2020.08.04 |
---|---|
SQL을 사용하여 데이터베이스 테이블의 열 이름을 바꾸려면 어떻게합니까? (0) | 2020.08.04 |
DialogFragment에 인수 전달 (0) | 2020.08.04 |
내용 편집 가능한 추가 방지 (0) | 2020.08.04 |
위조 방지 토큰 문제 (MVC 5) (0) | 2020.08.04 |