압축 구조가 C 언어의 일부가 아닌 이유는 무엇입니까?


10

모든 C 컴파일러는 C 구조를 "포장"하는 옵션을 제공합니다 (예 : __attribute__ ((__packed__))또는 #pragma pack()). 신뢰할 수있는 방식으로 데이터를 보내거나 저장하려면 패킹이 필요하다는 것을 모두 알고 있습니다. 이것은 C 언어의 첫날 이후의 요구 사항이었습니다.

그래서 패킹 된 구조가 C 언어 사양의 일부가 아닌 이유가 궁금합니다. 그것들을 가질 필요성이 현재 수십 년 동안 알려져 있지만 C99 또는 C11에도 없습니다. 내가 무엇을 놓치고 있습니까? 왜 컴파일러 특정입니까?


2
그들은 아닌 순수 C 코드를 작성하는 데 필요한.
user253751

답변:


7

타겟 CPU / 컴파일러의 조합에 따라 다르기 때문입니다. 이것은 언어 측면보다 컴파일러 지시어가 더 낫다는 것을 의미합니다. 그들이 할 수있는 유일한 방법은 노조와 함께하는 것입니다.

Raymond의 기사는 이것이 왜 그런지에 대한 통찰력을 제공합니다 : http://www.catb.org/esr/structure-packing/


매우 흥미로운 기사. (+1)
조르지오

"12 바이트를 보유하는 구조가 필요합니다. 필드 X는 오프셋 0에서 4 옥텟 리틀 엔디안으로 저장된 32 비트 정수로 동작해야합니다. 필드 Y는 64 비트 정수로 동작해야합니다. 오프셋 4 "에서 8 진수 바이트 리틀 엔디안으로 저장 되었습니까? 어떤 플랫폼에서든지 처리하는 코드는 컴파일러가 비트 필드에 대해 이미 가지고있는 종류보다 나쁘지 않아야하며 프로그래머가 기본 컴퓨터와 일치하는 정렬을 지정하는 경우 훨씬 효율적일 수 있습니다. 다른 컴퓨터에서는 효율성이 떨어지지 만 여전히 휴대 가능합니다.
supercat

5

세 가지 주요 요소가 있습니다.

  1. 일부 프로세서는 정렬되지 않은 데이터 (예 : 홀수 주소에서 시작하는 정수 또는 부동 소수점)에 액세스 할 수 없습니다. 시도하면 예외가 발생합니다.
  2. 일부 프로세서는 정렬되지 않은 데이터에 액세스 할 수 있지만 성능이 저하됩니다.
  3. 대부분의 구조는 단일 C / C ++ 소스 코드 세트로 액세스되며 다른 언어와의 상호 운용성은 예외가 아니라 예외입니다.

이러한 요소를 염두에두고 표준 및 모든 C / C ++ 컴파일러는 일반적으로 프로세서에 대한 최적의 정렬을 보장하기 위해 구조를 패딩하지만 interop의 목적으로 필요한 경우이를 재정의하는 메커니즘을 제공합니다.

이것은 결코 간과 된 것이 아닙니다. 그것은 매우 잘 이해되고 있으며 현재 상황은 의도적으로 설계된 것입니다. 최신 버전의 C ++ 표준은 익숙하지 않은 정렬 문제 처리를 광범위하게 지원합니다.


패킹 된 구조에 대해 제기 될 수있는 모든 논거는 비트 필드를 선택적 기능으로 만드는 것을 정당화하는 데 사용될 수도 있습니다. 패킹 된 구조의 멤버에 액세스하는 것은 일부 프로세서에서는 느리고 다른 프로세서에서는 빠를 수 있지만, 컴파일러가 정렬되지 않은 액세스 기능이없는 사용자 코드 해결 방법을보다 효율적인 코드로 바꾸려고하는 것은 단순히 컴파일러가 프로그래머가 무엇을 지정하도록하는 것보다 훨씬 복잡합니다. 그들은 필요.
supercat

@ supercat : 당신은 무엇을 주장하고 있습니까? 나는 그것을 얻지 못한다.
david.pfx

비트 필드는 선택 사항이어야한다고 생각하지만 비트 필드가 필수 기능이 될 경우 구조체 레이아웃을 명시 적으로 제어 할 수있는 방식으로 비트 필드를 확장하는 것이 좋습니다. 그렇지 않으면 결과적으로 컴파일러는 레이아웃을 완전히 제어하는 ​​데 필요한 작업의 90 %를 수행해야하지만 프로그래머는 10 %의 이점 만 얻을 수 있습니다.
supercat

@supercat : 비트 필드는 정수이며 정수와 동일한 비트 레이아웃 순서 규칙을 따릅니다. 구현 정의. 스트럭쳐 멤버는 선언 된대로 문자 경계에서 정렬되며 패킹이 삽입 된 상태입니다. 그것들은 개념 상 상당히 분리되어 있습니다. [제안을 확장하려면 다른 질문을해야하지만 전혀 효과가 없다고 생각합니다.]
david.pfx

0

표준이 아니기 때문에 컴파일러마다 다릅니다. 그리고 강제적 인 정렬 제한이있는 불분명 한 플랫폼의 컴파일러를 위해 많은 구현 노력을 필요로하지 않는 방식으로 지정하기가 어렵 기 때문에 표준에는 없습니다.

C89 이상 컴파일러를 사용하는 모든 컴파일러 / 플랫폼에서 이미 구현 한 모든 컴파일러 / 플랫폼이 있기 때문에 그 노력 중 어느 것도 정당화 할 수 없습니다.


2
??? 당신은 "표준 언어가 아니기 때문에"표준에 있지 않기 때문에 "왜 표준 언어에 있지
않습니까

그것이 내가 먼저 생각한 것이지만 다시 한번, "structed가 키워드 'packed'로 정의되면 그 크기는 각 개별 멤버의 추가 된 크기와 동일하다는 것이 보장됩니다. 지원하지 않는 플랫폼에서 정렬되지 않은 메모리 액세스, 구조체 멤버 값 중 하나에 대한 액세스는 정의되지 않은 동작입니다. " 이것은 최소한 개별적인 멤버의 구조체 크기와 오프셋을 알 수있는 정렬되지 않은 플랫폼의 개발자를 허용 할 것입니다.
grasbueschel

1
바이트 배열과 같은 구조체를 구현하고 각 필드의 값을 읽고 쓰는 데 필요한 비트 이동 및 &/ |작업을 수행하여 하드웨어에서 지원하지 않는 시스템에서 정렬되지 않은 액세스 작업을 수행 할 수 있습니다.
dan04

1
@ dan04 : 많은 프로세서에서 컴파일러는 일련의 바이트 읽기 및 시프트를 사용하는 것보다 더 효율적인 정렬되지 않은 액세스를위한 코드를 생성 할 수 있습니다. 이를위한 구문을 사용하면 프로그래머가 바이트를 더 긴 유형으로 어셈블하기 위해 코드를 작성하려고 시도하는 다른 모든 방식을 인식하도록 요구하는 것보다 효율적인 컴파일러가 코드를 더 쉽게 생성 할 수 있습니다.
supercat
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.