2014-12-03 2 views
0

현재 임베디드 코드 포트 (Freescale S12)에서 작업 중이므로 GNU와 나는 노동 조합에 문제가 있습니다. 난 다음 노동 조합통합 및 메모리 정렬 관련 문제

typedef signed short  sint16; 
typedef signed long   sint32; 

typedef union 
{ 
    sint32 Akku; 
    sint16 AkkuHigh; 
    sint16 AkkuLow; 
} akku_type; 

을 가지고 내가 노동 조합의 가장 높은 2 바이트를 액세스하려는. 문제는 AkkuHigh와 AkkuLow가 Akku와 같은 시작 주소를 가지고 있다는 것입니다. 그것은 컴파일러 특정 것으로 보인다. 내 질문은 : 노조의 동작을 변경하는 컴파일러 플래그가 있습니까? 공물 ((align (2))) 도와 드릴까요?

AkkuLow가 같은 주소를 가지고, Akku의 모든 AkkuHigh, 사전

+0

'익명의 내부 구조체'에'high'와'low' 필드를 포함하십시오. 엄밀히 말하자면 이식성이 없지만 작동해야합니다. –

+1

왜 다른 주소를 갖기를 기대 했습니까? – Borgleader

+0

@ 박영배 : C는 그것을 허용하고, 일반적인 C++ 확장 기능입니다. 왜위원회가 동굴에 들어 가지 않고 합법화하지 않았는지 궁금해 ... – Deduplicator

답변

3

예에 감사드립니다. 이것은 unions이 C에서 작동하는 방법입니다.이 모양에 따라 32 비트 멤버와 2 개의 16 비트 멤버로 이루어진 멤버 인 멤버를 사용하여 유니온을 만들려고했습니다. 당신이 쓴 것은 그것을 성취하는 방법이 아닙니다. 대신보십시오 : 노동 조합의

typedef union 
{ 
    sint32 Akku; 
    struct s { 
     sint16 AkkuHigh; 
     sint16 AkkuLow; 
    } representation; 
} akku_type; 
+0

'AkkuHigh'가 상위 바이트이고 'AkkuLow'가 하위 바이트가 될 것이라고 보장됩니까? 컴파일러가 그들을 바꾸기로 결정할 수 없습니까? – Unapiedra

+0

@Unapiedra 구조체의 멤버 주소가 순서대로 유지된다는 보장이 있습니다. 이러한 주소가 일치하는 것은 구현에 따라 다릅니다 (일반적으로 대상 아키텍처의 endianness에 따라 다릅니다. 대부분의 빅 엔디안 아키텍처에서 쓰여진 구조체가 작동합니다). –

+0

@Unapiedra : 주위를 바꾸는 것은 허용되지 않지만,'struct' 멤버 다음에 임의의 (구현 정의 된) 양의 패딩을 추가하는 것은 그것들 앞에 있습니다. – Deduplicator

0

올바른 정의는 this answer에서 찾을 수 있습니다.

atribute(align(2))은 32 비트 또는 64 비트 아키텍처에서 컴파일 할 때 분명 도움이 될 것입니다. 또한, 64bit sizeof(sint32)8 (64 비트)입니다.

아키텍처의 엔디안에 따라 AkkuHighAkkuLow을 교환해야 할 수 있습니다.

+0

C++의 공통 확장이지만 유효한 C이지만 C++은 아닙니다. – Deduplicator

+0

정확히 C++이 아닌 것은 무엇입니까? 이름없는 구조체? – axiac

+0

예. 이름없는 익명 멤버입니다. 당신이 그것을 고칠 때 핑 (ping). – Deduplicator

관련 문제