2013-01-19 1 views
2

나는 std/boost :: function보다 더 간단하고 (더 빠르며) 똑같은 것을 쓰고있다. 나의 가장 큰 관심사는 단순성과 효율성이다. 플랫폼은 gcc와 clang으로 컴파일 된 x86-64 linux로 제한되어있다. 위의 제한에서 64 비트 리눅스에서 함수 포인터 크기

, 그것은 공정

  1. 모든 함수 포인터, 즉, 포인터 (함수, 멤버 함수를 무료로 가정하는 것입니다 POD의 가상 방법, 파생 클래스, 사실상 상속 클래스 클래스. ..), functor, lambda ... 모두 최대 16 바이트 크기입니까?
  2. 그리고 정렬 요구 사항은 무엇입니까?
+1

아니요. 'sizeof' 이유가 존재합니다. –

+2

대답은 여전히 ​​동일합니다. ** 아니요, 아무 것도 생각하지 않아도됩니다 **. –

+0

그는 효율성이 중요하다고 말했다. 때로는 효율성을 높이기 위해 일을 맡아야하는 경우가 있으며 때로는 유형의 크기에 관한 것을 가정하는 경우도 있습니다. – thang

답변

1

x86_64의 경우 함수 및/또는 멤버에 대한 포인터가 멤버 함수에 대한 포인터의 크기를 초과하지 않는다고 안전하게 가정 할 수 있습니다. GCC의 경우이 값은 sizeof(void*)입니다. clang의 경우 이것은 sizeof(void*)*2 (마지막으로 확인한 시간)입니다. 정렬 요구 사항은 16 바이트입니다. GCC를 사용하면 __BIGGEST_ALIGNMENT__ 미리 정의 된 매크로를 사용할 수 있습니다. 그러나 clang에는 결석이 ​​있습니다. 내가 제안 할 수있는 유일한 방법은 가정하지 말고 가장 큰 크기를 계산하는 컴파일 타임 식을 사용하는 것입니다.

UPDATE : @ 데이비드로

가 8 바이트 여러 및/또는 가상 상속의 경우 멤버 함수 호출을 파견하기 위해 충분하지 않을 수 있습니다 지적했다. 따라서 안전한 측면을 유지하기 위해 두 경우 모두 sizeof(void*)*2이 적용됩니다.

가장 좋은 방법은 sizeof을 사용하는 컴파일 타임 표현식입니다. 예를 들면 다음과 같습니다.

struct Foo { 
}; 

typedef void* (Foo::*pmf)(); 
typedef void* (*bar)(); 

constexpr auto max_func_pointer_size() -> decltype(sizeof(void*)) { 
    return sizeof(pmf) > sizeof(bar) ? sizeof(pmf) : sizeof(bar); 
} 

int main() 
{ 
    static_assert(max_func_pointer_size() == 16, "oops!?"); 
} 
+0

블라드에게 감사드립니다. 정말 도움이됩니다. 그리고 BIGGEST_ALIGHMENT의 경우, 나는 alignas (16) 만 할 수 있다고 생각합니다. –

+0

하향 투표하지는 않지만 "안전한 가정"과 같은 것은 존재하지 않습니다. "우와 나를 엉덩이로 만드는 것을 추측합니다"라는 오래된 말의 이유가 있습니다. 다시 한번, 'sizeof'가 존재하기 때문에, 그것. –

+0

@KenWhite : 당신 말이 맞아. 내가 대답하는 이유는 gcc와 clang 모두에서 무슨 일이 일어나는 지 알고 있기 때문이다. 나는 몇 달 전부터 이것을 해왔다. 물론 아무것도하지 않고 가정하는 것은 좋지 않다. d 컴파일 시간 검사 등을 사용합니다. 이것은 현재 두 컴파일러에서 모두 작동하는 것입니다. –

관련 문제