ปัญหา
ในบริบทฝังโลหะเปลือยระดับต่ำฉันต้องการสร้างพื้นที่ว่างในหน่วยความจำภายในโครงสร้าง C ++ และไม่มีชื่อใด ๆ เพื่อห้ามไม่ให้ผู้ใช้เข้าถึงตำแหน่งหน่วยความจำดังกล่าว
ตอนนี้ฉันทำได้สำเร็จแล้วโดยการใส่uint32_t :96;
บิตฟิลด์ที่น่าเกลียดซึ่งจะแทนที่สามคำได้อย่างสะดวก แต่มันจะขึ้นคำเตือนจาก GCC (Bitfield ใหญ่เกินไปที่จะใส่ใน 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 อื่น ๆ แม้ว่าการสร้างโครงสร้างจะเป็นสคริปต์ก็ตาม
ข้อความเตือนที่แน่นอนมีดังนี้:
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
ธงที่จะลบคำเตือนนี้ ...
char unused[12];
และอื่น ๆ ?