C 指向volatile结构的不透明指针

C 指向volatile结构的不透明指针,c,struct,volatile,C,Struct,Volatile,我在我的嵌入式C程序中使用了一个简单的FIFO环形缓冲队列(使用TI C28x C/C++编译器,它与GCC for C89非常相似,没有扩展)。 数据通过队列从中断中推送和弹出,因此队列需要是可变的 我在没有使用volatile的情况下实现了队列代码本身,因此队列用户可以选择队列是否为volatile(我希望在具有不同用途的多个项目中使用它),方法是在用法中声明句柄为volatile queue对象,而不是在实现中将队列对象本身定义为volatile i、 e.在问题c中: struct QU

我在我的嵌入式C程序中使用了一个简单的FIFO环形缓冲队列(使用TI C28x C/C++编译器,它与GCC for C89非常相似,没有扩展)。 数据通过队列从中断中推送和弹出,因此队列需要是可变的

我在没有使用volatile的情况下实现了队列代码本身,因此队列用户可以选择队列是否为volatile(我希望在具有不同用途的多个项目中使用它),方法是在用法中声明句柄为volatile queue对象,而不是在实现中将队列对象本身定义为volatile

i、 e.在问题c中:

struct QUE_Obj { /* Object & members are not defined as volatile. */
    void * data;
    uint16_t capacity;
    uint16_t head;
    uint16_t tail;
    uint16_t size;
    bool full;
    bool empty;
}

/* Implementation uses all non-volatile types. */
QUE_Handle QUE_init(void * data, uint_least8_t size, uint16_t capacity) { 
    /* ... */ 
    QUE_Handle q = (QUE_Handle)malloc(sizeof(struct QUE_Obj));
    /* ... */
    return q;
}

/* ... */
在队列中。h:

typedef QUE_Obj * QUE_Handle;
QUE_Handle QUE_init(void * data, uint_least8_t size, uint16_t capacity)
总而言之,c:

/* Data buffer and queue handle declared to be for volatile data. */
static volatile uint16_t buffer[BUFFER_LENGTH] = {0};
volatile QUE_Handle que = QUE_init((void *)buffer); /* Buffer passed without volatile. */
然后,我的问题是,在C中的最后一行,当我将缓冲区转换为
void*
时,这会消除波动性的任何有用性吗

我是否应该将
QUE_Obj
的成员定义为始终可变,并将实现中使用的类型调整为可变,而不考虑队列的使用


换一种方式问,从中断服务例程调用
push()
pop()
函数,但是它们的实现不“知道”波动性,它们会被优化掉吗?

您不应该通过非波动性指针访问波动性数据。考虑下面的简单例子:

volatile int volatileVar;
int* nonVolatilePtr = &volatileVar;
每当您的代码通过
nonVolatilePtr
访问
volatileVar
时,编译器都不知道您正在访问的数据是不稳定的,并且可能会优化对它的访问(这显然是一种不希望出现的行为)。我很少看到非易失性指针对易失性数据的使用


如果您希望您的队列可能被中断服务例程(或类似程序)访问,我会使整个数据结构不稳定。

如果试图通过使用左值和非不稳定限定类型引用由不稳定限定类型定义的对象,
行为未定义。
您可能应该使用volatile声明指针。说吧。@太好了,谢谢你的标准报价!感谢您的示例(假设您的意思是“通过
nonVolatilePtr
”@Toby Good catch:)编辑以澄清,您的意思是我至少需要
volatile int*ptr=&volatileVar
volatile int*volatile ptr=&volatile int
volatile int*ptr=&volatileVar正常。它声明一个指向可变整数的指针。使用
volatile int*volatile ptr=&volatile int您正在声明一个指向一个易失性整数的指针,该整数也是易失性的,这意味着对指针本身的访问也不应该优化(这似乎不是您的情况)。