2017-11-09 18 views
-1

이 주제에 관해서는 이미 질문이 있습니다 (특히 How to get address of some struct member in array of structures).지도 파일의 멤버 구조체 주소?

제 질문은 다음과 같습니다. struct을 사용하여 하드웨어 장치를 설명 할 때 각 구조 구성원이 하드웨어 장치의 일부 레지스터에 해당합니다. 구조의 각 구성원이 올바르게 매핑되는지 어떻게 확인할 수 있습니까? 하드웨어의 각 레지스터?

컴파일러의 ABI가 멤버의 정렬을 지정하면 사용자가 실수를 할 수도 있습니다. 매핑이 올바르게 수행되었는지 확인하는 유일한 방법은 런타임에 확인하는 것입니다. 맵 파일 (적어도 GNU ld의 경우)은 구조체 멤버의 배치에 대한 단서를 제공하지 않습니다.

각 구조 구성원이있는 컴파일러 또는 링크 시간을 알 수있는 방법이 있습니까?

+1

정확합니다. 이식성있는 방법으로는 불가능합니다. 당신은 특정 컴파일러의 확장 및/또는 동작에 의존해야 할 것입니다. – Ctx

+0

이것은 어쨌든 특정 시스템입니다. 코드를 완전히 다른 종류의 컴퓨터로 옮기면 하드웨어 장치가 없을 것입니다. –

+0

절대적으로 동의합니다. (CPU, 컴파일러)에 따라 다릅니다. 그러나 동일한 CPU 및 동일한 컴파일러를 사용하더라도 매핑에 실수가 없음을 확인하고 Map 파일을 통해 구조 멤버의지도를 표시 할 수있는 방법을 찾고 있습니다. 그러나 유일한 방법은 런타임에 해당 주소를 표시하는 코드 조각을 갖는 것입니다. –

답변

2

offsetof과 함께 C++에서 static_assert을 사용할 수 있습니다. 예를 들어

, 컴파일러는 64 비트 경계에 구성원을 정렬 때문에 static_assert 예를 들어, 실패

#include <cstddef> 
struct iom {  // off,len 
    uint32_t rx; // +0,4 
    uint32_t tx; // +4,4 
    uint64_t clk; // +8,8 
    uint16_t irq; // +16,2 
}; 
static_assert(offsetof(iom,rx)==0); 
static_assert(offsetof(iom,tx)==4); 
static_assert(offsetof(iom,clk)==8); 
static_assert(offsetof(iom,irq)==16); 

경우 완전히 임의의, 당신은 정렬과 패딩을 변경하는 컴파일러 구체적인 방법이 필요합니다. 예를 들어, gcc의 경우

} __attribute__((packed)); 

구조체 정의의 끝에.


NB. 나는 C++에 대해 대답했다.

C11 또는 14 또는 C11은 static_assert의 두 번째 인수로 오류 메시지가 필요하지만 매크로에서 모든 것을 래핑하여 멋진 문자열을 작성할 수 있습니다.

offsetof 매크로도 C 언어로 작동합니다.

+0

확인을 요청 해 주셔서 감사합니다. 나는 몰랐습니다. – Useless

+0

은 제 컴파일러 (C11)와 함께 훌륭하게 작동합니다 - Thx !! –