C 如何匿名申报

C 如何匿名申报,c,struct,embedded,unions,C,Struct,Embedded,Unions,我有以下问题:我试图定义一些基本的结构,它帮助我映射控制器内存的一部分,以便以更有效的方式使用它。让我举一个例子: typedef struct { ICR1_t ICR1_dByte; /* 0x46 - 0x47 */ OCR1B_t OCR1B_dByte; /* 0x4A - 0x4B */ OCR1A_t OCR1A_dByte; /* 0x48 - 0x49 */ TCNT1_t TCNT1_dBy

我有以下问题:我试图定义一些基本的结构,它帮助我映射控制器内存的一部分,以便以更有效的方式使用它。让我举一个例子:

typedef struct
{
    ICR1_t      ICR1_dByte;    /* 0x46 - 0x47  */
    OCR1B_t     OCR1B_dByte;   /* 0x4A - 0x4B  */
    OCR1A_t     OCR1A_dByte;   /* 0x48 - 0x49  */
    TCNT1_t     TCNT1_dByte;   /* 0x4C - 0x4D  */
    TCCR1B_t    TCCR1B_Byte;   /* 0x4E */
    TCCR1A_t    TCCR1A_Byte;   /* 0x4F */
    uint8_t     Filler[8];     /* 0x50-0x57 */
    TIFR1_t     TIFR1_Byte;    /* 0x58 */
    TIMSK1_t    TIMSK1_Byte;   /* 0x59 */
}Timer1_str;
用法定义:

#define TIMER1str (*(volatile Timer1_str *)(TIMER1_START_ADDRESS))
其中,计时器1\u开始\u地址定义为

(uint8_t *)&ICR1
(ICR1是基本定义的一部分,一些地址,没关系)

所以,我的特别问题是如何填补内存中的空白,位于0x50-0x57地址下?在当前解决方案中,变量“Filler”在所有自动补码工具下都可见,因此可以调用字段:

TIMER1str.Filler[0] = 0xAA;
我希望隐藏该填充的实现。我的第一个想法是将此填充程序实现为匿名联盟,如下所示:

...
    TCCR1A_t    TCCR1A_Byte;   /* 0x4F */
    union { Filler[8]; };      /* 0x50-0x57 as anonymous */
    TIFR1_t     TIFR1_Byte;    /* 0x58 */
....
但是这个解决方案不起作用


如何隐藏成员的结构?它应该设置内存,但不应可访问。

C不支持此功能。匿名嵌套结构和联合不会隐藏成员,它们只允许您像访问包含类的成员一样访问成员

一种可能是使用C++编译,如果编译器支持的是:

struct Timer1_str
{
    public :
        ICR1_t      ICR1_dByte;    /* 0x46 - 0x47  */
        OCR1B_t     OCR1B_dByte;   /* 0x4A - 0x4B  */
        OCR1A_t     OCR1A_dByte;   /* 0x48 - 0x49  */
        TCNT1_t     TCNT1_dByte;   /* 0x4C - 0x4D  */
        TCCR1B_t    TCCR1B_Byte;   /* 0x4E */
        TCCR1A_t    TCCR1A_Byte;   /* 0x4F */
    private :
        uint8_t     Filler[8];     /* 0x50-0x57 */
    public :
        TIFR1_t     TIFR1_Byte;    /* 0x58 */
        TIMSK1_t    TIMSK1_Byte;   /* 0x59 */
} ;

看起来你在为AVR编码

不要这样做。使用编译器提供的这些寄存器的定义


正如所写的,您的代码指定
Timer1\u str
结构将存在于系统内存中由链接器确定的某个位置。如果没有任何额外的支持,此代码将无法工作,因为此结构将映射到SRAM,导致对它的写入没有特殊效果。即使使用链接器将此结构映射到适当的地址(这可能是可能的,也可能是不可能的),编译器生成的用于处理该结构的代码也将是次优的,因为它将无法使用
IN
OUT
指令来操作这些寄存器。(要生成这些指令,必须在编译时知道写入的地址。)此外,编译器可能会生成无法正确访问这些寄存器的代码-例如,在这里,它可能会以错误的顺序生成对TCNT的写入。

所有Cpp编译器是否都保证,结构中的数据将按输入顺序直接定位?@user2759473:好问题。是的,我相信是这样,但包装和校准可能会有所不同。建议使用编译器的打包指令。最终,您的芯片或编译器供应商几乎肯定会提供一个定义外围寄存器访问的头,正如Daskwulf所指出的,这可能是一个更好的解决方案。+1…例如,AVR libc有Hello,事实上,您是对的,提到这是针对AVR的,然而,它是AVR开发人员向我们提供的解决方案的包装。事实上,问题更多地集中在实际方法上,即在其他结构中定义匿名联合/数组,以便能够“跳过”某些地址。