2014-10-05 2 views
1

다음의 정의는 (3.9/4) 주어진다다른 alingment 요구 사항을 가진 서로 다른 유형의 두 객체가 동일한 객체 표현을 가질 수 있습니까? 객체의 표현

형 T 의 물체의 객체 표현가 서명 숯불 오브젝트는 오브젝트가 차지하는 N의 시퀀스이고 형식 T 인 경우 N은 크기 (T)와 같습니다. ,

charsigned char을하고 unsigned char는 스토리지의 동일한 양을 차지 가 동일한 배향 요구 (3.11);

하지만 3.9.1/1 말한다 즉, 은 동일한 객체 표현을가집니다.

정렬 요구 사항에 따라 개체 표현이 달라집니다. 그러나 내가 인용 한 정의에는 언급되지 않았다. 그것은 동일한 크기의 두 객체가 서로 다른 객체 표현을 가질 수 있습니다.

본질적으로 나는 다음에 대해 묻고 있습니다. 그 중 하나의 정렬이 다른 것과 같은 크기의 두 개의 객체가 있다고 가정 해보십시오. 예를 들면 다음과 같습니다.

struct A 
{ 
    char a; 
    char b; 
    char c; 
    char d; 
}; 

A a; //Object 1. alignof(a) = 1 
int b; //Object 2. alignof(b) = 4 

이러한 개체는 동일한 개체 표현을 사용합니까?

+0

실질적인 동기 부여 예제로 사용될 수있는 코드가 있다면 도움이 될 것입니다. –

+2

@JohnZwinck 불행히도 아니오, 아닙니다. 그것은 순수한 이론적 인 질문입니다. –

+1

다른 타입 안에 수동으로 지정된 정렬을 가진 타입이 중요 할 것이라 확신합니다. – o11c

답변

1

어떻게 정렬 작품에 대한 약간의 혼동이있다. 네 말이 맞아

오브젝트 표현은 정렬 요구 사항에 따라 달라집니다 :

객체 표현 유형 서명 숯불의 (T) 개체를 sizeof의 순서입니다

동안

개체의 값 표현은 해당 형식의 값을 보유하는 비트 집합입니다. T

당신은 예를 들어 다음과 같은 유형이 걸릴 경우

struct S { 
    char c; // 1 byte value 
      // 3 bytes padding 
    float f; // 4 bytes value 
    bool operator==(const S& arg) const { // value-based equality 
     return c == arg.c && f == arg.f; 
    } 
}; 
assert(sizeof(S) == 8); // object representation 

8 바이트의 객체 표현의 크기 계정 만 다른 하나에 대한 개체의 값을 결정 5 바이트의 값 표현 크기 계정을. 차이를 유발하는 맞춤 요구 사항이 있으며 패딩이 일부 도입됩니다.

예제에서 유형은 객체 표현 및 값 표현에 대해 동일한 크기를 가지며 객체 표현 크기는 값 표현 크기와 같습니다. 여기에 다른 무엇

struct A 
{ 
    char a; 
    char b; 
    char c; 
    char d; 
}; 

A a; //Object 1. Object representation size = 4, value representation size = 4, alignof(a) = 1 
int b; //Object 2. Object representation size = 4, value representation size = 4, alignof(b) = 4 

는 정렬이 저장하고 객체에 액세스 할 수 필요합니다.

4 바이트가 아닌 주소에서 4 바이트 정수에 액세스하는 일부 프로세서에서는 치명적인 오류가 발생합니다. 스 니펫에 사용 된 alignof 키워드는 정확히 다음과 같이 말합니다. 1 바이트 정렬 주소 (즉, 어디서나)에 유형 A의 객체를 할당해야합니다. 단일 바이트의 하위 객체에 최대 단일 읽기로 액세스 할 것이므로 어디서나 액세스 할 수 있어도 안전합니다. 어쨌든에 안전하게 액세스하려면 4 바이트의 정렬 된 주소에 정수를 할당해야합니다.

§3.11/P1

개체 유형 맞춤 요구 사항 (3.9.1, 3.9.2)하는 대신 그 유형의 오브젝트가 가 할당 될 수있는 어드레스에 제한. 얼라인먼트가 주어진 객체에 할당 될 수있는 에서 연속적인 어드레스 사이의 바이트 수를 나타내는 구현 정의 정수 값 이다

수단

:는 4 바이트 정렬 된 어드레스에 정수를 할당해야 영광되지 않은 정렬 요구 사항이 시스템 - 인 경우 무슨 일이 일어날 것

|0x07|0x08|0x09|0x0A|0x0B|.. 
    > I can allocate an integer here, on a 4-bytes-aligned address 
> Here the buffer starts 
     |------------------| 
     object rep size == value rep size 

통지 것을 :하지만 개체 의 시작 부분에 당신의 버퍼의 시작부터 필요한 바이트 개체의 일부가되지 않습니다 종속성, 즉x86에서 성능이 저하되고 SSE로 인해 충돌이 발생할 수 있습니다. GPU 메모리 공간에서는 프로그램을 복구 할 수 없습니다. 이 표준은 단지 정렬 할당 요청에 관해서 일이 무엇인지를 지정한다 : 특정 상황 에서 특정 확장 정렬에 대한 요청이 구현에 의해 지원되지 않는 경우

는, 프로그램이 잘못 형성된다. 또한 요청 된 정렬을 적용 할 수없는 의 동적 저장소 런타임 할당에 대한 요청은 할당 실패로 처리됩니다.

+0

철저한 답변 주셔서 감사합니다. –

0

단일 바이트 문자의 경우 정렬은 부적절하므로 (1 바이트 경계) 인용 된 예제가 true로 유지됩니다. 그러나 더 진보 된 상황에서는 그렇지 않습니다.

일반적으로 경험적으로 n 바이트 개체는 n 바이트 경계에 저장해야합니다. 프로세서 수준에서 잘못 정렬 된 개체에 대한 작업을 시도하면 예외가 발생합니다. 그래서 (최적화)없이

:

PTR64  *a; 
INT32  b; 
INT16  c; 
BYTE  d; 

8 + 4 + 2 + 1 = 15 바이트 일 것이다. 그러나 :

BYTE  a; 
INT16  b; // preceded with (1) bytes to 16 bit boundary 
INT32  c; // Preceded with (2) bytes to 32 bit boundary 
PTR64  *d; // preceded with (4) bytes to 64 bit boundary 

ㄴ 것이다 1+ (1) +2+ (2) +4+ (4) = 21 바이트 +8.

+0

"프로세서 수준에서 잘못 정렬 된 개체에서 작업을 시도하면 예외가 발생합니다." x86 및 x86-64를 포함하여 오늘날 사용되는 가장 일반적인 프로세서 중 일부는 아닙니다. 오류가 발생할 수 있지만 그렇게 할 필요는 없습니다. –

+0

따라서 "일반적인 경험 법칙". 이 예외는 또한 정렬되지 않은 경우 클럭 사이클을 추가하는 것 이외의 16 비트 경계 개념을 거의 또는 전혀 갖지 않는 단순한 8 비트 임베디드 시스템에도 적용됩니다. – Mike

0

물론 가능합니다.
intchar [4] 정확히 같은 크기, 다른 개체 표현을 생각해보십시오.

는 또한 reinterper_cast 및 언어 union 있습니다. 이들은 서로 다른 오브젝트 유형과 동일한 바이트를 조사하는 데 도움이됩니다.

그래서, 당신의 예를 작업, 같은 실제 바이트에 INT의 조합, 그리고 구조체를 할 수 :

struct A 
{ 
    char a; 
    char b; 
    char c; 
    char d; 
}; 

union MyUnion 
{ 
    A a; 
    int b; 
}