2014-10-16 10 views
0

pragma pack과 같이 구조체/클래스 레이아웃을 제어하기 위해 다양한 pragma이 있습니다. 그러나 내가 아는 한, "나는 레이아웃을 신경 쓰지 않는다. 내부적으로, 코드는 의존하지 않는다. 최고의 성능/크기를 위해 순서를 바꾸어 라."라고 말하면서도 pragma은 없다. AFAIK, 전형적인 경우이며 많은 경우 성능/크기를 향상시킬 수 있습니다. 또한 프로그래머가 성능/크기에 맞게 재정렬 할만큼주의를 기울 였지만 다른 대상 아키텍처가 다른 최적의 레이아웃을 가질 수 있습니다.struct/class 레이아웃에 신경 쓰지 않는 pragma가 있습니까? 그렇지 않다면, 왜?

편집 :, 회원의 순서에 대해 이야기하고 있습니다. 패딩은 이미 제어 가능합니다.

또한 PVS-Studio에는 관련 message이 있습니다. 그게 내가 말하는거야. 왜 이걸 컴파일러에서 pragma으로 할 수 없습니까?

+0

데이터 멤버를 재정리 할 수있는 것을 의미합니까? – juanchopanza

+0

@ juanchopanza : Paul이 패딩에 대해 묻는 것처럼 보입니다. –

+0

@ juanchopanza, 예, 설명이 추가되었습니다. – Paul

답변

1

이러한 pragma는 언어 표준에 의해 허용되지만, 그런 것을 구현하는 컴파일러는 알지 못합니다. C에서

, #pragma의 문제는 (링크가 최신 초안이다) the standard의 섹션 6.10.6에 규정되어

형태의 전처리 지시자
# 프라그PP-토큰 옵트 개행
전처리 토큰 STDC는 이 구현 정의 방식으로 동작하도록 구현 발생 지향성 (전 모든 매크로 여분 행)에 pragma을 즉시 수행하지 않는다. 이 동작으로 인해 번역이 실패하거나 변환기 또는 결과 프로그램이 일치하지 않는 방식으로 작동하게 할 수 있습니다. 이러한 구현은 구현에서 인식되지 않습니다.

은 그래서 #pragma은 사실상 언어의 규칙을 위반.

이 경우 관련 규칙은 구조체 멤버가 선언 된 순서대로 배치된다는 것입니다. 6.7.2.1 항 15 : 구조 개체 내에서

은 비트 필드가있는 에서 비 비트 필드 회원들과 단위는이 선언되고 의 순서로 증가 주소를 가지고있다. 적절히 으로 변환 된 구조체 개체에 대한 포인터는 초기 멤버 (또는 해당 멤버가 비트 필드 인 경우 해당 멤버가 상주하는 단위)를 가리키고 그 반대의 경우도 마찬가지입니다. 구조체 개체 내에 이름이없는 패딩이있을 수 있지만 시작 부분은 이 아닙니다.

나쁜 소식 : C 표준은 구조체 멤버가 선언 된 순서대로 배치되도록 요구합니다. 첫 번째 멤버는 오프셋 0에 있어야합니다. 멤버간에 또는 임의의 멤버 사이에 임의의 패딩이있을 수 있지만 재정렬 할 수는 없습니다.

좋은 소식 : 위의 규칙에 위배되는 레이아웃을 지정하는 #pragma을 정의 할 수있는 언어입니다.

나쁜 소식 : 내가 아는 한 실제로 어떤 구현도 그렇게하지 않습니다. 그렇더라도 구현하지 않은 다른 구현이 있으므로 이러한 #pragma을 사용하는 코드는 이식 할 수 없습니다. (최소한 #pragma의 이름이 고유하더라도 인식하지 못하는 컴파일러는이를 무시해야하므로 코드는 여전히 컴파일됩니다.)

#pragma의 C++ 규칙은 매우 비슷합니다. C 규칙과 비슷합니다. 나는 합리적으로 구조체 레이아웃에 대한 C++ 규칙이 C와 비슷하다는 것을 확신합니다. 상속은 일을 좀 더 복잡하게 만듭니다.

2

이 언어에서는 클래스 멤버가 각 액세스 수준 (예 : private)에있는 것과 같은 방식으로 메모리에 정렬된다는 것을 명시하고 있습니다. pragma가이 동작을 무시할 수있는 방법은 없습니다.

9.2/14 참조 : A (비 노조)의

비 정적 데이터 멤버 클래스를 수 있도록 할당 된 동일한 액세스 제어 (11 항) 나중에 멤버가 클래스 객체 내에서 높은 주소를 가지고 . 다른 액세스 제어 비 정적 데이터 멤버의 할당의 순서는 멤버를 재정렬하는 하위 오브젝트 생성자와 소멸자가 호출되는 순서를 변경 명심

지정되지 않은, 그리고 아마도 다른 것들입니다. 컴파일러가 이러한 종류의 변경을 수행하기위한 pragma를 제공하더라도 매우 위험합니다 (다른 멤버의 초기화에 의존하는 멤버가있는 경우에는 어떻게됩니까?).

+1

이 답변의 예를 들어 두 가지 속성에 유의하십시오. http://stackoverflow.com/a/11770476/47453 두 가지 모두 C 및 C++ 표준에 의해 금지 된 방식으로 구조 레이아웃을 변경합니다. 그러나 그들은 여전히 ​​존재합니다. 그들은 단지 비표준 행동을 일으킨다. –

+0

나는 그것이 액세스 수준에 관계없이 클래스에서 선언 된 순서라고 생각했습니다. –

+0

@neilkirk 저 또한 제 이해였습니다.'private''''''''''''''''''는 단순히 다른 프로그래머들에게 본질적으로 강요된 (그리고 쉽게 피할 수있는) 힌트입니다. – fluffy