컴파일러가 생성하는 코드에는 데이터 구조에 대한 실제 지식이 없으며 (어셈블리 수준에 존재하지 않기 때문에) 옵티마이 저도 마찬가지라는 사실을 인식하는 것이 중요합니다. 컴파일러는 데이터 구조가 아닌 각 함수에 대한 코드 만 생성 합니다 .
좋아, 그것은 또한 상수 데이터 섹션 등을 씁니다.
이를 바탕으로 옵티마이 저가 데이터 구조를 출력하지 않기 때문에 멤버를 "제거"하거나 "제거"하지 않을 것이라고 이미 말할 수 있습니다. 멤버를 사용 하거나 사용 하지 않을 수있는 코드를 출력 하며, 그 중 목표는 멤버의 무의미한 사용 (즉, 쓰기 / 읽기)을 제거하여 메모리 나주기를 절약 하는 것입니다.
요점은 "컴파일러가 함수의 범위 (인라인 된 함수 포함) 내에서 사용되지 않는 멤버가 함수가 작동하는 방식 (및 반환하는 내용)에 아무런 차이가 없음을 증명할 수 있는 경우 구성원의 존재로 인해 오버 헤드가 발생하지 않습니다. "
함수와 외부 세계와의 상호 작용을 컴파일러에게 더 복잡하거나 불명확하게 만들면 (예 : 더 복잡한 데이터 구조를 가져 오거나 반환합니다. 예를 들어 std::vector<Foo>
, 다른 컴파일 단위에서 함수 정의 숨기기, 인라인 금지 / 비 인센티브 화 등) , 컴파일러가 사용하지 않는 멤버가 효과가 없음을 증명할 수 없을 가능성이 점점 더 높아집니다.
컴파일러가 수행하는 최적화에 따라 다르기 때문에 여기에는 엄격한 규칙이 없습니다.하지만 YSC의 답변에 표시된 것과 같은 사소한 작업을 수행하는 한 오버 헤드가없는 반면 복잡한 작업 (예 : 반환 std::vector<Foo>
인라인에 대한 너무 큰 함수로부터는) 아마도 오버 헤드가 발생합니다.
요점을 설명하기 위해 다음 예를 고려 하십시오 .
struct Foo {
int var1 = 3;
int var2 = 4;
int var3 = 5;
};
int test()
{
Foo foo;
std::array<char, sizeof(Foo)> arr;
std::memcpy(&arr, &foo, sizeof(Foo));
return arr[0] + arr[4];
}
여기서는 사소한 일을하지 않지만 ( 바이트 표현 에서 주소를 가져오고, 검사하고, 바이트를 추가 ) 최적화 프로그램은이 플랫폼에서 결과가 항상 동일하다는 것을 알아낼 수 있습니다.
test(): # @test()
mov eax, 7
ret
멤버 Foo
들은 어떤 기억도 차지 Foo
하지 않았을뿐만 아니라 존재조차하지 않았다! 최적화 할 수없는 다른 용도가있는 경우 예를 들어 sizeof(Foo)
문제가 될 수 있지만 해당 코드 세그먼트에만 해당됩니다! 모든 사용이 이와 같이 최적화 될 수 있다면 eg의 존재 var3
는 생성 된 코드에 영향을 미치지 않습니다. 그러나 다른 곳에서 사용 되더라도 test()
최적화 된 상태로 유지됩니다!
요약 :의 각 사용은 Foo
독립적으로 최적화됩니다. 일부는 불필요한 멤버로 인해 더 많은 메모리를 사용할 수 있지만 일부는 그렇지 않을 수 있습니다. 자세한 내용은 컴파일러 설명서를 참조하십시오.