문제
A의 낮은 수준의 베어 메탈 (bare-metal) 임베디드 환경, 나는 액세스 메모리 위치에 사용자를 금지하기 위해, C ++ 구조 내에서 어떤 이름없이, 메모리에 빈 공간을 만들고 싶습니다.
지금 uint32_t :96;
은 세 단어를 편리하게 대신 할 추악한 비트 필드를 배치하여 달성 했지만 GCC (uint32_t에 맞기에는 비트 필드가 너무 큼) 경고가 발생합니다. 이는 매우 합법적입니다.
잘 작동하지만 수백 개의 경고가있는 라이브러리를 배포하려는 경우에는 그다지 깨끗하지 않습니다.
어떻게 제대로 수행합니까?
애초에 문제가있는 이유는 무엇입니까?
제가 작업중인 프로젝트는 전체 마이크로 컨트롤러 라인 (STMicroelectronics STM32)의 다양한 주변 장치의 메모리 구조를 정의하는 것으로 구성됩니다. 이를 위해 결과는 대상 마이크로 컨트롤러에 따라 모든 레지스터를 정의하는 여러 구조의 결합을 포함하는 클래스입니다.
매우 간단한 주변기기의 간단한 예는 다음과 같습니다. GPIO (범용 입 / 출력)
union
{
struct
{
GPIO_MAP0_MODER;
GPIO_MAP0_OTYPER;
GPIO_MAP0_OSPEEDR;
GPIO_MAP0_PUPDR;
GPIO_MAP0_IDR;
GPIO_MAP0_ODR;
GPIO_MAP0_BSRR;
GPIO_MAP0_LCKR;
GPIO_MAP0_AFR;
GPIO_MAP0_BRR;
GPIO_MAP0_ASCR;
};
struct
{
GPIO_MAP1_CRL;
GPIO_MAP1_CRH;
GPIO_MAP1_IDR;
GPIO_MAP1_ODR;
GPIO_MAP1_BSRR;
GPIO_MAP1_BRR;
GPIO_MAP1_LCKR;
uint32_t :32;
GPIO_MAP1_AFRL;
GPIO_MAP1_AFRH;
uint32_t :64;
};
struct
{
uint32_t :192;
GPIO_MAP2_BSRRL;
GPIO_MAP2_BSRRH;
uint32_t :160;
};
};
모두 GPIO_MAPx_YYY
가 매크로이며 uint32_t :32
또는 레지스터 유형 (전용 구조) 으로 정의됩니다 .
여기에서 uint32_t :192;
잘 작동 하는 것을 볼 수 있지만 경고가 발생합니다.
지금까지 고려한 사항 :
나는 그것을 여러 개 uint32_t :32;
(여기서는 6 개) 로 대체했을 수도 있지만, 내가 가진 극단적 인 경우 uint32_t :1344;
(42 개)가 있습니다. 따라서 구조 생성이 스크립팅 되었음에도 불구하고 8k 다른 것 위에 약 100 줄을 추가하지 않을 것입니다.
정확한 경고 메시지는 다음과 같습니다.
width of 'sool::ll::GPIO::<anonymous union>::<anonymous struct>::<anonymous>' exceeds its type
(저는 그것이 얼마나 그늘진 지 좋아합니다).
차라리 것 없는 단순히 경고를 제거하여이 문제를 해결하지만, 사용
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-WTheRightFlag"
/* My code */
#pragma GCC diagnostic pop
내가 발견하면 ... 해결책이 될 수 있습니다 TheRightFlag
. 그러나, 지적 이 스레드 , gcc/cp/class.c
이 슬픈 코드 부분 :
warning_at (DECL_SOURCE_LOCATION (field), 0,
"width of %qD exceeds its type", field);
-Wxxx
이 경고를 제거 할 플래그 가 없음을 알려줍니다 .
uint32_t :192;
.
:42*32
대신 쓸 수있는 BTW:1344
char unused[12];
했습니까?