我使用以下类型:
/* double_buffer.h */
typedef struct
{
uint8_t * active_buffer_p; //< Address of active buffer
uint8_t current_writing_index; //< Current writing index in active buffer
uint8_t buffer_1[BUFFER_SIZE]; //< First buffer
uint8_t buffer_2[BUFFER_SIZE]; //< Second buffer
} double_buffer_t;
#define DoubleBuffer_init(buffers) do { \
(buffers).active_buffer_p = (buffers).buffer_1; \
(buffers).current_writing_index = 0; \
} while(0)
在我的代码中,我使用volatile键声明了一个双缓冲区数组(因为缓冲区可以在中断和函数中异步更新/读取):
static volatile double_buffer_t m_double_buffers[NB_DOUBLE_BUFFERS];
然后,我分别初始化这些缓冲区:
DoubleBuffer_init(m_double_buffers[id]);
当我编译软件(gcc)时,我得到了以下警告:
error: assignment discards 'volatile' qualifier from pointer target type [-Werror=discarded-qualifiers]
28 | (buffers).active_buffer_p = (buffers).buffer_1; \
为什么我有这个警告的原因是我很不清楚,我不知道如何修复它。
任何帮助将不胜感激(我可以更新的问题,如果有什么不清楚)。
2条答案
按热度按时间jm81lzqq1#
您收到此警告是因为您有一个volatile对象,并且您创建了一个指向它的非volatile指针。
这是很糟糕的,因为编译器可以访问volatile对象而不知道它是volatile对象。例如,它可以将两次读取转换为一次读取,它可以改变顺序等。
一种解决方法是将
active_buffer_p
定义为uint8_t volatile * active_buffer_p
。vvppvyoh2#
当您将一个
struct
变量声明为volatile
时,每个成员对象都会获得volatile
限定,就像您这样编写结构一样:也就是说,在指针成员的情况下,指针本身转向
volatile
。type* volatile
=指针的地址可能在任何时候改变,而不是它应该指向的地方。volatile type*
=所指向的数据可能在任何时候改变。所以当你赋值的时候,
buffer_1
“数组衰减”为volatile uint8_t*
,然后你试图把它赋值给一个被限定为uint8_t* volatile
的指针,指针类型是不兼容的,因为它们有不同的限定符。解决方法是声明指针成员
volatile uint8_t* active_buffer_p;
,然后如果结构体变量声明为volatile
,它就变成volatile uint8_t* volatile
(指针和它所指向的对象可能随时改变),我们总是可以将一个“非限定”指针赋给一个有更多限定符的指针,但不能反过来。const
的工作方式完全相同。顺便说一句,init宏很难看,除了混淆之外没有任何用途。考虑放弃它,以支持可读代码:
或100%等效: