2013-05-14 4 views
3

명백한 이유로 C 컴파일러는 플랫폼의 호출 규칙 및 기타 ABI 요구 사항을 준수하도록 다른 공유 라이브러리에서 외부에서 볼 수있는 모든 함수를 컴파일해야합니다. 그러나 필자는 외부 모듈에서 절대 호출 할 수없는 기능을 위해 반드시 그렇게 할 필요는 없다는 것을 배웠습니다.C 컴파일러는 호출 규칙을 무시할 수 있습니까?

컴파일러가 해당 함수에 대해 true인지 여부를 어떻게 그리고 언제 결정할 수 있습니까?

  • 정적 함수는 동일한 컴파일 단위의 다른 함수에서만 볼 수 있으므로 이러한 ABI- 위반 최적화에 적합한 후보가됩니다. 그러나 정적 함수에 대한 함수 포인터는 여전히 다른 모듈로 전달 될 수 있습니다. 컴파일러는 함수 포인터가 코드의 아무 곳이나 전달되는지 확인하려고합니까?

  • gcc 컴파일러에는 심볼을 기본값, 숨김 또는 내부로 선언 할 수있는 some extensions이 있으며 설명서에는이 정보를 사용하여 외부에서 볼 수있는 funcitons에서는 불가능했던 몇 가지 종류의 최적화를 수행 할 수 있다고 명시되어 있습니다. 함수 포인터가 내부 코드로 주석 처리 된 함수의 외부 코드에 전달되면 어떻게됩니까?

다른 라이브러리와의 상호 운용성을 보장하면서 가능한 한 많은 최적화를 수행하는 데 도움이되는 가장 좋은 방법은 무엇입니까? 컴파일러 옵션을 사용하여 모든 함수를 내부로 정의하고 외부에서 표시해야하는 모든 함수의 특성으로 재정의해야합니까?

답변

0

정적 함수는 동일한 컴파일 단위의 다른 함수에서만 볼 수 있으므로 이러한 ABI- 위반 최적화에 적합한 후보가됩니다. 그러나 정적 함수에 대한 함수 포인터는 여전히 다른 모듈로 전달 될 수 있습니다. 컴파일러는 함수 포인터가 코드의 아무 곳이나 전달되는지 확인하려고합니까?

예, 컴파일러는 주어진 함수가 실제로 내부에서만 사용되는지 또는 포인터를 통해 이스케이프되는지 여부를 확인하기 위해 "이스케이프 분석"을 수행합니다.

GCC 컴파일러는 기호는 기본, 숨겨진 또는 내부로 선언 할 수 있도록 몇 가지 확장 기능을 가지고 있으며, 문서는 특히이 정보가 외부에 표시 funcitons에 대한 최적화의 몇 가지 종류의 불가능을 수행 할 수 있음을 언급하고있다. 함수 포인터가 내부 코드로 주석 처리 된 함수의 외부 코드에 전달되면 어떻게됩니까?

처음 대답을보십시오.

1

C 표준 은 모든 경우에 동일한 함수에 대한 두 개의 포인터가 동등한 비교를 필요로한다는 것을이 필요로합니다.

심볼을 외부 으로 선언하면 컴파일러는 ABI 브레이크 트릭을 수행 할 수 있습니다. 포인터는 절대 외부 코드로 전달되지 않습니다.

컴파일러는 함수 포인터가 코드의 어느 곳에서나 으로 전달되는지 확인하려고합니까?

예. 최적화를 수행하려는 경우 예. 컴파일러는 어떤 함수에 함수 포인터 감쇠가 수행되었는지 쉽게 알 수 있으므로 함수의 주소를 사용했는지 여부를 알면 큰 문제는 아닙니다. 보수적으로, 컴파일러는 모든 함수 포인터가 외부 코드로 전달된다고 가정하거나 더 진보 된 것으로 시도 할 수 있습니다.

함수 포인터가 내부 코드로 주석 처리 된 함수에 대해 외부 코드 에 전달 된 경우 어떻게됩니까?

아무런 관심을 끌지는 못합니다. 작동해야합니다.

내부/외부 가시성은 대부분 가시성에 관한 것입니다. 컴파일러는 비교적 적은 경우에만 ABI를 깨뜨리기 위해 라이센스로 전환 할 수 있습니다.

난 그냥 내부로 모든 기능을 정의하기 위해 컴파일러 옵션을 사용하여 외부에서 볼 수 있어야합니다 모든 기능에 대한 속성과 그를 오버라이드 (override) 할 필요가?

라이브러리가 하나의 번역 단위로만 구성되어 있지 않으면 사실상 모든 기능을 외부에서 볼 수 있어야합니다. "외부 (External)"사이에는 의미있는 차이가 없습니다. "내 라이브러리에서만"과 "외부에서 모두"사이에는 의미있는 차이가 없습니다. 그러나 이론 상으로는 이것을 시도 할 수 있습니다. 그러나 나는 당신이 많은 스피드 업을 성취 할 수 있다는 것을 의심 스럽다. 그리고 이것은 사소한 코드베이스에 많은 노력을 기울일 것이다.

+0

일부 ARM 시스템에서는 부동 소수점 값이 다른 매개 변수와 동일한 방식으로 전달 될 것으로 예상되는 코드와 FP 레지스터에서 호환성 문제가있을 수 있습니다. 그것이 함수 포인터가 아니라면, FPU를 사용하는 코드를 생성하는 컴파일러가 FPU 레지스터를 사용하는 맹 글링 된 이름을 가진 함수 버전을 생성하고, "weakly-linked"래퍼가 일반 매개 변수를 FPU 레지스터에 복사하고 변형 된 버전을 호출하는 un-mangled 이름입니다. – supercat

+0

FPU를 사용하고 FPU 레지스터 버전을 호출하려는 컴파일러 proudicng 코드는 변환 된 이름 버전에 대한 호출을 생성하고 FPU 레지스터를 일반 매개 변수에 복사하고 비 맹 글링 버전을 호출하는 약 링크 된 래퍼를 생성합니다 . 이렇게하면 호출자와 호출 된 코드 FPU 사용간에 "보편적 인"동작이 허용됩니다. 함수 포인터에 관해서는, 나는 ABI 분산의 문제를 피할 수 있다고 생각한다. "특별히"선언하지 않는 한 그들은 항상 가장 기본적인 ABI를 사용하는 방법을 가리킨다. 그게 효과가있는 것 같습니까? – supercat

관련 문제