2013-08-20 7 views
10

저는 C++ 11, constexpr의 새로운 기능을 실험하고 있습니다. 내가 것 템플릿 포로를 코딩 할 경우 단순히 수행constexpr 대 템플릿, pow 함수

//pow 
template<class T, std::size_t n> 
struct helper_pow{ 
    inline static T pow(T const& a){ 
     return a*helper_pow<T,n-1>::pow(a); 
    } 
}; 

//final specialization pow 
template<class T> 
struct helper_pow<T,0>{ 
    inline static T pow(T const& a){ 
     return 1; 
    } 
}; 

을 지금에 의해 간단하게 내 코드에 내 함수를 호출하는 경우 (것

pow<double,5>(a) // where a is double 

해당 조립 GCC 4.8. 0, -O2) :

movapd %xmm0, %xmm1 
    movsd %xmm0, 24(%rsp) 
    mulsd %xmm0, %xmm1 
    movq %rbx, %rdi 
    mulsd %xmm0, %xmm1 
    mulsd %xmm0, %xmm1 
    mulsd %xmm0, %xmm1 

코드가 미세합니다.

나는 constexpr 버전을 찾고 있어요 알고 있다면, 나는 해당 어셈블리가 지금

template <class T> 
inline constexpr T pow(T const& x, std::size_t n){ 
    return n>0 ? x*pow(x,n-1):1; 
} 

있습니다

movsd 24(%rsp), %xmm2 
    leaq 24(%rsp), %rdi 
    movl $4, %esi 
    movsd %xmm2, 8(%rsp) 
    call __Z3powIdET_RS0_m 

기능 __Z 번호의 powIdET_RS0_m는

LCFI1: 
    mulsd %xmm1, %xmm0 
    movapd %xmm0, %xmm2 
    mulsd %xmm1, %xmm2 
    mulsd %xmm2, %xmm1 
    movapd %xmm1, %xmm0 
    ret 
으로 정의 보이는 경우

그래서 constexpr을 사용하면 함수가 인라인이 아니며 "외부 "기능? 그것은 constexpr 함수의 인라인을 강제하는 방법이 존재합니까? 최고.

+1

constexpr 'pow'에 대한 인수가 const가 아닌 이유는 무엇입니까? –

+0

g ++ 4.8.1 ('-O2')의 디스 어셈블리를 올바르게 해석했다면 지수가 리터럴 (컴파일시 알려진 것) 인 경우 작은 지수에 대해'pow '를 인라인 (in recall)하고 재귀를 푸십시오. - 시간 충분해야한다). 큰 지수 (예 : 10)의 경우 함수를 도입합니다. '-O3'에서 더 높은 지수 (14)에 대해서도 인라인을합니다. – dyp

+0

Sebastian : 나는 잊는다.^_ ^, DyP : 흥미 롭다. 새로운 버전의 컴파일러를 시도해 보겠다. –

답변

1

인라인은 컴파일러에 대한 힌트에 불과합니다. 그것은 무엇이든 원하는대로 할 수 있습니다. 함수에 대한 인라이닝을 강제 또는 해제하기 위해 pragma 및 __declspec과 같은 컴파일러 관련 항목이 있습니다.

constexpr 버전 간섭의 비 const 왼쪽 값 참조가 될 수 있습니다. 당신은 어쨌든 가치에 힘을 합격해야합니다.

1

constexpr 함수 템플릿의 특정 인스턴스화가 상수 표현식이 필요한 컨텍스트에서 사용하려고하지 않는 한 실제로 constexpr이 아니어도 오류가 아닙니다. 어쩌면 인스턴스화 된 템플릿은 constexpr이 아닙니다. 컴파일러가 불평

constexpr double powtest = pow(2.0, 5); 

경우, 당신이 뭔가 잘못 알고 :

발견하려면,이 작업을 수행.

+0

맞습니다.이 기능을 알고 있습니다. 글쎄, 나는 현재의 구현을 템플릿으로, constexpr에 의해 하나의 "동적"파라미터로 바꾸기를 원했다. –

+3

아, 근본적으로 컴파일러가 오래된 버전을 인라인하고 새로운 버전을 인라인하지 않을까 걱정된다. 그것은 흥미 롭습니다. 특히 부분적으로 constexpr 함수를 전문적으로 다루었 기 때문입니다. –

+0

예, 인라인은 많은 스택 관리를 제거합니다. 신중하게 규범을 읽고 기능에 대한 GCC 포럼의 질문을 게시해야합니다. –