2013-08-03 2 views
0

Buddies, 과학 연구 중에 질문이 생겼습니다. 컴파일 시간에 평가 된 값을 출력 할 수 있습니까? 컴파일러가 컴파일 시간 동안 표현식을 평가한다는 것은 확실합니다. 요점은 컴파일하는 동안 어떻게 평가 된 값을 출력 할 수 있습니까? 한 가지 방법은 오류를 강제로하지만 매우 우아하지 않은 것 같습니다. TMP를 사용하고 싶다면 할 수 있습니까? 감사.C++에서 컴파일 타임 동안 템플릿 메타 프로그래밍을 사용하여 평가 된 값을 출력 할 수 있습니까?

+0

보통 어떻게 든 값을 템플릿 매개 변수로 표시하는 컴파일러 오류가 발생합니다. – jrok

+0

몇 가지 샘플을 보여줄 수 있습니까? 정확히보고 싶은 것이 있습니까? 이를 수행하는 표준 방법은 컴파일러에서 생성 된 어셈블리 코드를 읽는 것입니다. –

+0

어떤 코드로 출력하고 싶은 평가를 보여주십시오. – user2029077

답변

1

정수 상수 식의 값을보고 싶다고 가정하면 디버깅 목적으로 값을 볼 수있는 쉬운 방법은 해당 값으로 오류를 만드는 것입니다. 예를 들면 :

template <int> struct constexpr_debugger; 

int main() { 
    const int i0(4), i1(17); 
    constexpr_debugger<i0 + i1> debug; 
} 

이 코드를 컴파일 할 때 난 당신이 값에 관심이 여전히 컴파일 코드를 얻고 싶다면, 가장 좋은 방법 내가 알고 있어요

constexpr_debugger.cpp: In function ‘int main()’: 
constexpr_debugger.cpp:5:37:error: aggregate ‘constexpr_debugger<21> debug’ has incomplete type and cannot be defined 
     constexpr_debugger<i0 + i1> debug; 
            ^

메시지를 얻을 예를 들어, 사용되지 않는 변수를 기반으로 경고 메시지를 작성하는 것입니다. 경고는 표준에서 결코 요구되지 않으므로 컴파일러의 비트와 경고가 표시 될 때 사용되는 플래그에 따라 다릅니다. gccclang으로 테스트 해보면 위의 클래스 템플릿을 간단하게 정의하면 컴파일러가 불행히도 템플릿 매개 변수의 값을 표시하지 않는다는 것을 알 수 있습니다.

template <int> 
void constexpr_debugger() 
{ 
    int debug; 
} 

int main() { 
    const int i0(4), i1(17); 
    constexpr_debugger<i0 + i1>(); 
} 

GCC는 따라서, 원하는 값에 대한 debug 사용되지 않는 경고의 템플릿 매개 변수 및 포함 기능을 언급 : 컴파일러들이 자신의 진단에서보고 무엇에 차이가 [현재] 다음 코드를 보여줍니다. clang은 debug에 대해서도 경고하지만 문제가 발생하는 템플릿 인스턴스화는 언급하지 않습니다. 당신은 당신이 사용하고있는 컴파일러와 함께 작동하는 형태의 무언가를 필요로 할 것입니다 (아마도 여러분이 사용하고있는 컴파일러 버전에 맞추어 져야 할 것입니다).

0

이후 C++ 11 constexpr 컴파일 시간

실시 예에서 평가하는 것이 발현을 활성화하는데 사용될 수있다 : 평가 된 식을 사용 템플릿 메타 프로그래밍을 표시

constexpr int sqr(int x) 
{ 
return x*x; 
} 

int a[sqr(4)]; //Compiles with C++11 and a has 16 elements. 

template<unsigned int n> 
struct dummy ; 

int main() { 
     char<dummy1<dummy<1 + 55-2>::dummy2>()); //Obliviously wrong 
     return 0; 
} 

컴파일러 오류 :

error: incomplete type 'dummy<54u>' used in nested name specifier

0

컴파일 오류 또는 경고를 사용하지 않으려면 형식 정보를 개체 파일의 기호에 넣을 수 있습니다. 다음 프로그램은 컴파일 시간 목록을 위해 그렇게 할 것입니다.

// Just define the types we need to construct lists. 
template <typename Head, typename Tail> struct Cons {}; 
struct Nil {}; 

// This is what you want to output. 
using MyOutput = Cons<int, Cons<float, Cons<char, Nil>>>; 

// Template function declaration. 
template <typename TheOutput> 
void MyOutputFunc() {} 

// Explicitly instantiate the template function with the desired output. 
template void MyOutputFunc<MyOutput>(); 

출력 검색은 컴파일러 및 OS 고유 일 것입니다. 다음은 Linux에서 g ++의 경우를 보여줍니다.

$ g++ -c -std=c++11 a.cpp 
$ nm a.o | grep MyOutputFunc 
0000000000000000 W _Z12MyOutputFuncI4ConsIiS0_IfS0_Ic3NilEEEEvv 
$ nm a.o | grep MyOutputFunc | cut -d ' ' -f3 | c++filt 
void MyOutputFunc<Cons<int, Cons<float, Cons<char, Nil> > > >() 

할 수 있습니다 이런 유형에 그들을 배치하여 출력 정수 :

template <typename T, T value> 
struct WrapValue {}; 

using MyOutput = WrapValue<int, 15>; 

이 디버깅 반대로 다양한 지원 정보를 검색하는 데 더 유용합니다.예를 들어이 방법의 사용 사례는 일부 마이크로 컨트롤러 소프트웨어의 구성 옵션과 관련이 있으며 컴파일 시간 출력은 템플릿 프로그램이 구성 옵션을 EEPROM 메모리에 매핑 한 방법입니다.

관련 문제