GDB에서 일부 C++ 코드를 디버깅하던 중 일부 호출이 소위 '합성 포인터'를 사용하고 있다는 사실을 발견했습니다. 인터넷 검색을 해도 의미 있는 결과를 얻지 못했습니다. SO에서 검색해보니 제목에 '합성'이 들어간 대부분의 질문은 Java 기능을 언급하고 있었습니다(이 문맥에서 '합성'은 '컴파일러가 인위적으로 생성한 것'을 의미할 수 있다고 제안하더라도요).
예를 들어, 이 백트레이스는 MyClass
의 생성자에서 m
이라는 하나의 클래스 멤버에 대해 수행된 하나의 연산에서 가져온 것입니다(이 코드는 -O2
로 컴파일되었습니다):
#0 MyClass (arg=..., this=<synthetic pointer>) at somefile.h:144
144 m->lock();
gdb$ print this
$1 = (MyClass * const) <synthetic pointer>
gdb$ print *this
$2 = <optimized out>
위의 스택 추적은 이것
이 최적화 된 객체에 대한 포인터라고 분명히 말하지만 어떻게 메서드 (즉, 생성자)가 호출되었을 수 있을까요? 제 추측으로는 동봉된 객체(m
)가 코드에서 활발히 사용되더라도 일부 최적화를 통해 컴파일러가 동봉된 객체(this
)가 실제로 필요하지 않다고 판단할 수 있다는 것입니다. 최적화할 수 없는 메서드 호출 m-
잠금()은 어딘가에서 방출되어야 하기 때문에 컴파일러는
m을 감싸기 위해 메모리 어디에도 없는
가짜` (합성?) 객체를 생성합니다.
나는 강력한 컴파일러 경험이 없기 때문에이 결론이 정말로 의미가 있는지 모르겠습니다. 누군가 이것에 대해 약간의 빛을 비춰 주시겠습니까?
감사합니다.
컴파일러는 이것
이 실제로 역참조되는지 여부를 판단할 수 있습니다(즉, 일반적인 C++ 규칙이 아닌 특정 CPU 세부 정보를 사용하여). 메서드가 실제로 이것
을 역참조하지 않는다면, 수학적 표현을 사용할 필요가 없습니다.
[편집]
댓글에서 jww는 다른 사례를 언급했습니다. 싱글톤은 복사본이 하나뿐이므로 똑똑한 컴파일러는 그 멤버를 전역으로 취급할 수 있습니다. 즉, 싱글톤-> foo
의 주소는 상수 & singleton + offset(foo)
일 뿐입니다. 이 최적화의 결과로 싱글톤 메서드는 싱글톤 멤버에 액세스하기 위해 실제로 이것
을 역참조할 필요가 없으므로 다시 최적화할 수 있습니다.