문제

시스템은 특정 프리미티브가 메모리 내의 특정 지점에 정렬되도록 요구합니다(int는 4의 배수인 바이트, short는 2의 배수인 바이트 등).물론 패딩에서 최소한의 공간을 낭비하도록 최적화할 수 있습니다.

내 질문은 왜 GCC가 이 작업을 자동으로 수행하지 않습니까?더 확실한 경험적 방법(가장 큰 크기 요구 사항에서 가장 작은 순서로 변수 순서 지정)이 어떤 면에서 부족합니까?일부 코드는 구조체의 물리적 순서에 의존합니까(좋은 생각입니까)?

나는 단지 GCC가 많은 면에서 매우 최적화되어 있기 때문에 묻는 것인데 이 경우에는 그렇지 않으며, 비교적 멋진 설명이 있어야 한다고 생각합니다(저는 인식하지 못합니다).

도움이 되었습니까?

해결책

gcc는 C 표준을 위반하므로 구조체 요소의 순서를 변경하지 않습니다.C99 표준의 섹션 6.7.2.1에는 다음과 같이 명시되어 있습니다.

구조 객체 내에서 비 ​​비트 멤버 및 비트 필드가 상주하는 단위는 선언 된 순서가 증가하는 주소를 갖습니다.

다른 팁

구조체는 바이너리 파일 형식과 네트워크 프로토콜의 패킹 순서를 나타내는 데 자주 사용됩니다.그렇게 하면 깨질 것입니다.또한, 서로 다른 컴파일러는 사물을 다르게 최적화하므로 두 가지 모두에서 코드를 함께 연결하는 것은 불가능합니다.이것은 단순히 실현 가능하지 않습니다.

GCC는 소스 코드에서 기계어 코드를 생성하는 데 있어서 우리 대부분보다 더 똑똑합니다.그러나 구조체를 재배치하는 데 있어서 그것이 우리보다 더 똑똑했다면 나는 몸을 떨었습니다.파일에 쓸 수 있습니다.4개의 문자로 시작하고 4바이트 정수를 갖는 구조체는 GCC가 구조체 멤버를 다시 정렬해야 한다고 결정한 다른 시스템에서 읽으면 쓸모가 없습니다.

gcc SVN에는 구조 재구성 최적화(-fipa-struct-reorg)가 있지만 전체 프로그램 분석이 필요하며 현재로서는 그다지 강력하지 않습니다.

C 컴파일러는 구조체를 자동으로 압축하지 않습니다. 바로 왜냐하면 당신이 언급한 것과 같은 정렬 문제.단어 경계(대부분의 CPU에서 32비트)가 아닌 액세스는 x86에서 큰 페널티를 초래하고 RISC 아키텍처에서 치명적인 트랩을 유발합니다.

좋은 생각이라고 말할 수는 없지만 구조체 멤버의 순서에 의존하는 코드를 작성할 수는 있습니다.예를 들어 해킹의 경우 사람들은 액세스하려는 내부의 특정 필드 유형으로 구조체에 대한 포인터를 캐스팅한 다음 포인터 연산을 사용하여 해당 위치에 도달하는 경우가 많습니다.나에게 이것은 매우 위험한 아이디어이지만 특히 C++에서 비공개로 선언된 변수가 제3자 라이브러리의 클래스에 있고 공개적으로 캡슐화되지 않은 경우 공개적으로 액세스할 수 있도록 강제하기 위해 사용되는 것을 보았습니다.멤버를 재정렬하면 완전히 깨질 것입니다.

최신 gcc 트렁크나 현재 개발 중인 struct-reorg-branch를 사용해 볼 수도 있습니다.

https://gcc.gnu.org/wiki/cauldron2015?action=AttachFile&do=view&target=Olga+Golovanevsky_+Memory+Layout+Optimizations+of+Structures+and+Objects.pdf

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top