2012-02-25 9 views
8

어떻게 GCC/"GNU C"에서 __attribute__((const)) 함수를 가리키는 함수 포인터를 선언합니까? 아이디어는 컴파일러에서 이전 호출의 반환 값을 캐시 할 수있을 때 함수 포인터를 통해 호출되는 함수에 대한 여러 호출을 생성하지 않도록하려는 것입니다. 이 질문에 확실히 대답은 아니지만함수 포인터 __attribute __ ((const)) 함수?

+0

그 일을하지 않고 거의 연구 잠들기하지만, CONST 속성을 가지고 있으며, 그 포인터를 받아들이는 명시 적으로 선언 함수와 같은 함수의 주소로 전화를 포장하려고했다 마십시오 매개 변수로. gcc가 포인터 주소 자체 및 인수가 변경되지 않는다고 판단 할 수 있으면 불필요한 호출을 제거해야합니다. –

+1

@Vlad : 나는 그것도 생각했지만 gcc는 내가 원하는 곳에서 함수를 인라인하는 것을 거부했다. 원래 래퍼 함수가 있었지만 인라인 동작을 수정하기 위해 제거했습니다. 흥미로운 경우 문제의 함수는'((pthread_t (*) (void)) 0xffff0fe0)'(Linux-ARM get-thread-pointer 함수)이다. –

+0

흥미로운 질문입니다. 저스틴의 대답에 원하는 결과가 있었습니까? – Praxeolitic

답변

3
typedef void (*t_const_function)(void) __attribute__((const)); 

static __attribute__((const)) void A(void) { 
} 

static void B(void) { 
} 

int main(int argc, const char* argv[]) { 
    t_const_function a = A; 

    // warning: initialization makes qualified 
    // function pointer from unqualified: 
    t_const_function b = B; 

    return 0; 
} 

또는 단지 :

__attribute__((const)) void(*a)(void) = A; 
+0

Bleh, 당신이 불쾌한 함수 포인터 타입을 가지고있을 때'typedef'는 항상 해결책입니다. 수락 됨. 그러나 'typedef'가없는 주요 질문에 대한 내 의견에 캐스트를 쓰는 방법이 있다면 어떤 생각이 들겠습니까? –

+0

@R. 불행히도, 나는'typedef '없이 하나의 문장으로 모든 것을 감을 방법을 모른다. GCC 4.2에서는 가능하지 않다. '((__attribute __ ((const)) pthread_t (*) (void)) 0xffff0fe0)'내가 어떻게 생각 하겠는가,하지만 당신이 원하는 것과는 다른 것으로 해석된다. (GCC는 리턴 타입에 속성을 적용하는 것처럼 보인다. 함수). – justin

0

, 당신은 아마이 알고 싶어 :

당신은 일반적인 경우에 컴파일러가 여기에 기대하는 최적화를 수행 기대할 수 없다. 컴파일러는 일반적인 경우 함수 포인터를 여러 번 사용하는 것이 동일한 함수에 해당한다는 것을 알기 위해 필요한 별칭 분석을 수행 할 수 없습니다.

포인터를 통한 두 함수 호출 사이의 함수 호출은 일반적으로 포인터 내용을 변경하여 호출 된 함수가 두 번째 호출에서 달라질 수 있습니다.

C의 특성으로 인해 적절한 별칭 분석을 수행하는 것이 종종 어려울 수 있으므로 이런 종류의 최적화가 발생하지 않을 수 있습니다.

+2

이것이 __attribute __ ((const))의 기능입니다. 컴파일러에서 사용자가 더 잘 알고 특정 최적화를 수행 할 수 있음을 알려줍니다. –

+0

내 경우에는 포인터가 주소 리터럴 (함수 포인터로 캐스팅 된 정수)이기 때문에 알 수 있습니다. 의견을보십시오. –

+2

@Vlad : Perry의 지적에 따르면, pointed 함수가 const 일지라도 컴파일러는 * 포인터 *가 호출간에 변경되지 않았 음을 확신해야합니다. 그러나 그것은 결정하기가 그리 어렵지 않습니다. 그리고 제 경우에는 문자 적 ​​절대 주소이기 때문에 불가능합니다. –