2017-02-27 14 views
1

공공 및 비공개 부분이 포함 된 D 모듈을 보유하고 있습니다. 함수 정의 전에 private 키워드와 static 키워드를 사용해 보았습니다. 나는 외부 호출 가능/공개로하고 싶어하고 이상적으로는 호출 사이트에서 인라인 될 수 있기를 바란다. 이 함수는 외부 호출 가능하지 않은 private 인 모듈 내부 함수를 호출합니다. 이것들에 대한 호출은 모듈 내에서 성공적으로 인라이닝되고 많은 cruft는 CTFE와 알려진 상수 전파에 의해 처리됩니다. 그러나 GDC 컴파일러는 필요할 때 어디에서나 인라인 될 수 있고 외부에서 호출 할 수없는 것으로 가정하더라도 이러한 내부 루틴의 사본을 생성합니다. -O3-frelease로 컴파일 중입니다. 내가해야 할 일은 무엇입니까? 정적이거나 사적으로 사용한다고해도 이것을해야합니까?D/DLang : 모듈 전용 비공개 인라인 함수의 코드 생성을 금지합니다.

통찰력을 기대하면서이 thread concerning GCC에 대해 간략히 살펴 보았습니다.

앞에서 언급했듯이이 두 가지 내부 함수를 개인용 및 정적으로 모두 사용하려고했지만 코드 생성을 억제 할 수는 없습니다. 디버거가 중단 점을 설정하기 위해 이러한 루틴을 복사해야 할 필요가 있다면 이것을 이해할 수 있습니다. 링크 타임에서 어떻게 든 정렬 될 수 있음을 강조 할 필요가 있습니다. 프로그램 연결을 시도하지 않았지만 GDC를 사용하는 Matt Godbolt D 컴파일러 탐색기에서 생성 된 코드를보고 있습니다. 모든 것은 템플릿 매개 변수의 길이가 0 인 목록 (예 : auto_fn() (arg_t x))을 사용하여 템플릿으로 만들 수 있습니다. 시도했지만 아무런 해가되지 않습니다.

시도해 볼만한 다른 몇 가지 : 패키지를 구현하는 방법 인 Ada 스타일로 개인 부분으로 정적 클래스를 만들 수 있습니다. (엄격히 싱글 인스턴스가 필요합니다.) 저는 C++을 전혀 해본 적이 없으며 엄청난 양의 asm과 C 만 전문적으로 수행했습니다. 그래서 그것은 학습 곡선이 될 것입니다.

내가 생각할 수있는 유일한 또 다른 점은 중첩 된 함수 정의, 파스칼/에이다 스타일을 사용하여 내부 루틴을 호출자 본문 내부로 이동시키는 것입니다. 그러나 그것은 많은 단점이 있습니다.

거친 예는

module junk; 

auto my_public_fn() { return my_private_fn(); } 

private 
static // 'static' and/or 'private', tried both 
auto my_private_fn() { xxx ; return whatever; } 
+0

현재 루틴에 일부 GCC 관련 확장 된 asm 코드가 포함되어 있기 때문에 LDC와 GDC를 비교할 수 없었습니다. 나는 원하지 않는 함수 몸체가 asm btw를 포함하는 함수 몸체가 아니라는 것을 알아 차렸다. –

+1

당신은 확실히'정적'이 필요하지 않습니다. 최상위 선언에는 의미가 없습니다. – Cauterite

+1

"나는 프로그램 연결을 시도하지 않았습니다."- GDC에 대해 많이 알지는 못했지만 링크 시간에 dead-code-elimination/COMDAT- 폴딩이 발생하여 이러한 함수가 사라질 수 있습니다. 아마도 GDC는 링커가 어쨌든 그것을 처리 할 것으로 예상되기 때문에이 수준에서 DCE를 시도하지 않습니다. 나는 단지 추측하고 있지만 ... – Cauterite

답변

2

난 그냥 이것에 대해 이안 짧은 토론을했고,이를 구현하는 것은 보인다 간단하지 않습니다. 모든 static

먼저 D에 많은 의미를 가지고 있지만, 번역 단위 지역의 기능의 C의 의미는 private 직관적 보인다

그래서 이러한 기능을 표시 ;-) 그 중 하나가 아닙니다. 결국 번역 단위 외부에서 함수에 액세스 할 수없고 함수에 주소가 누출되지 않는 이유는 무엇입니까? 이 경우 완전히 사용되지 않거나 모든 발신자에게 인라인 될 수 있습니다.

지금 여기 캐치의 : 함수가 사용되지 않는 경우 우리는 확실히 알 수 없습니다

private void fooPrivate() {} 

/*template*/ void fooPublic()() 
{ 
    fooPrivate(); 
} 

는 GDC는 fooPublic 템플릿에 대해 아무것도 (알고 파일을 컴파일 할 때 템플릿은 완전히 인스턴스화 할 때 분석 할 수)이므로 fooPrivate은 사용되지 않는 것 같습니다. 나중에 다른 파일에서 fooPublic을 사용할 때 GDC는 fooPrivate이 원본 소스에서 이미 방출 된 것으로 간주합니다. 결국 템플릿이 아니므로 새 모듈로 내보내지지 않습니다.

해결 방법이있을 수 있지만이 모든 문제는 중요하지 않은 것처럼 보입니다.또한 사용자 정의 gcc.attribute 속성을 도입 할 수 있습니다. 그것은 템플릿에서 같은 문제를 일으킬 것입니다. 그러나 하나의 유스 케이스에 대한 특정 주석이므로 (private과 달리) 우리는 옳은 일을하기 위해 사용자에게 의존 할 수 있습니다.

+0

별도의 조각을 포함하는 라이브러리로 obj 모듈을 구현하는 것처럼 링커에서이를 정렬 할 수 있습니까? (수십 년 전 거대한 프로젝트에서 한 번 손으로 이런 일을 한적이 있었음). 나는 그 일을하는 사람이 아니기에 쉽다. 악몽 일 수 있습니다. 나는 GCC C/C++이 무엇을하는지 전혀 모른다. –

+0

노력이 얼마나 가치가 있을지 모르겠다. 나는 CTFE에 의해 전적으로 고용 된 기능을 작성했거나 항상 인라인되었지만 생성 된 몸체는 사용되지 않아서 거기에 그대로 남아 있기 때문에 피로감을 느끼고있었습니다. –

+0

사용자가 함수 본문 배치, 열정 대 냉기 (GCC가 있습니까?)를 쉽게 제어 할 수 있다면 사용자가 사용하지 않는 함수 본문을 obj의 '콜드'끝에 모두 배치하거나 더 나은 모든 하위 섹션을 배치하는 것이 중요합니다. 함께 연결될 외부 섹션으로 이동합니다. –